En este artículo, analizamos el decorador de componentes en TypeDoc.
Demos un paso atrás y comprendamos primero qué es un decorador en TypeScript.
Un Decorador es un tipo especial de declaración que se puede adjuntar a una declaración de clase, método, accesor, propiedad o parámetro. Los decoradores usan la forma @expresión, donde la expresión debe evaluarse como una función que será llamada en tiempo de ejecución con información sobre la declaración decorada. - Fuente.
Por ejemplo, dado el decorador @sealed podríamos escribir la función sellada de la siguiente manera:
function sealed(target) { // do something with 'target' ... }
Elijamos un ejemplo simple y fácil de entender de la documentación de TypeScript sobre cómo usar el decorador de clases.
@sealed class BugReport { type = "report"; title: string; constructor(t: string) { this.title = t; } }
Aquí @sealed es un decorador de clase aplicado justo encima de la declaración de clase. Este @sealed es un decorador que se aplica en tiempo de ejecución.
Si desea evitar modificaciones en la clase BugReport, puede definir la función sellada como se muestra a continuación:
function sealed(constructor: Function) { Object.seal(constructor); Object.seal(constructor.prototype); }
Cuando se ejecuta @sealed, sellará tanto el constructor como su prototipo y, por lo tanto, evitará que se agregue o elimine cualquier funcionalidad adicional de esta clase durante el tiempo de ejecución accediendo a BugReport.prototype o definiendo propiedades en el propio BugReport: Fuente
Con este conocimiento, ahora estamos preparados para comprender el decorador @Component en el código base de TypeDoc.
El decorador @Component se importa desde lib/utils/components.ts
Esta es una fábrica de decoradores que devuelve una función de flecha que se ejecuta en tiempo de ejecución. Puede leer más sobre la fábrica de decoradores en los documentos de TS.
export function Component(options: ComponentOptions) { // _context is ClassDecoratorContext, but that then requires a public constructor // which Application does not have. return (target: Function, _context: unknown) => { const proto = target.prototype; if (!(proto instanceof AbstractComponent)) { throw new Error( "The `Component` decorator can only be used with a subclass of `AbstractComponent`.", ); } if (options.childClass) { if (!(proto instanceof ChildableComponent)) { throw new Error( "The `Component` decorator accepts the parameter `childClass` only when used with a subclass of `ChildableComponent`.", ); } childMappings.push({ host: proto, child: options.childClass, }); } const name = options.name; if (name) { proto.componentName = name; } // If not marked internal, and if we are a subclass of another component T's declared // childClass, then register ourselves as a _defaultComponents of T. const internal = !!options.internal; if (name && !internal) { for (const childMapping of childMappings) { if (!(proto instanceof childMapping.child)) { continue; } const host = childMapping.host; host["_defaultComponents"] = host["_defaultComponents"] || {}; host["_defaultComponents"][name] = target as any; break; } } }; }
Están sucediendo muchas cosas en este decorador de componentes; en lugar de tratar de entenderlo todo, retomemos las más fáciles que podemos deducir.
Esta verificación se utiliza para generar un error en caso de que la instancia no sea compatible.
2. proto.nombrecomponente
proto.componentName se actualiza según el nombre pasado al decorador. En este caso, el nombre se establece en "aplicación".
3. asignaciones infantiles
// If not marked internal, and if we are a subclass of // another component T's declared // childClass, then register ourselves as a _defaultComponents of T. const internal = !!options.internal; if (name && !internal) { for (const childMapping of childMappings) { if (!(proto instanceof childMapping.child)) { continue; } const host = childMapping.host; host["_defaultComponents"] = host["_defaultComponents"] || {}; host["_defaultComponents"][name] = target as any; break; } }
Se han realizado algunas actualizaciones en childMapping.host
En Think Throo, tenemos la misión de enseñar los conceptos arquitectónicos avanzados de base de código utilizados en proyectos de código abierto.
10 veces tus habilidades de codificación practicando conceptos arquitectónicos avanzados en Next.js/React, aprende las mejores prácticas y crea proyectos de nivel de producción.
Somos de código abierto: https://github.com/thinkthroo/thinkthroo (¡Danos una estrella!)
También brindamos servicios de desarrollo web y redacción técnica. Comuníquese con nosotros en [email protected] para obtener más información.
https://github.com/TypeStrong/typedoc/blob/master/src/lib/application.ts#L100
https://www.typescriptlang.org/docs/handbook/decorators.html
https://github.com/TypeStrong/typedoc/blob/master/src/lib/utils/component.ts#L39
https://www.typescriptlang.org/docs/handbook/decorators.html#decorator-factories
Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.
Copyright© 2022 湘ICP备2022001581号-3