Dans cet article, nous analysons le décorateur de composants dans TypeDoc.
Prenons du recul et comprenons d'abord ce qu'est un décorateur dans TypeScript.
Un Decorator est un type spécial de déclaration qui peut être attaché à une déclaration de classe, une méthode, un accesseur, une propriété ou un paramètre. Les décorateurs utilisent la forme @expression, où l'expression doit être évaluée comme une fonction qui sera appelée au moment de l'exécution avec des informations sur la déclaration décorée. - Source.
Par exemple, étant donné le décorateur @sealed, nous pourrions écrire la fonction scellée comme suit :
function sealed(target) { // do something with 'target' ... }
Choisissons un exemple simple et facile à comprendre dans la documentation TypeScript sur la façon d'utiliser le décorateur de classe.
@sealed class BugReport { type = "report"; title: string; constructor(t: string) { this.title = t; } }
Ici, @sealed est un décorateur de classe appliqué juste au-dessus de la déclaration de classe. Ce @sealed est un décorateur appliqué au moment de l'exécution.
Si vous souhaitez empêcher toute modification de la classe BugReport, vous pouvez définir la fonction scellée comme ci-dessous :
function sealed(constructor: Function) { Object.seal(constructor); Object.seal(constructor.prototype); }
Lorsque @sealed est exécuté, il scellera à la fois le constructeur et son prototype, et empêchera donc toute fonctionnalité supplémentaire d'être ajoutée ou supprimée de cette classe pendant l'exécution en accédant à BugReport.prototype ou en définissant des propriétés sur BugReport lui-même - Source
Grâce à ces connaissances, nous sommes maintenant prêts à comprendre le décorateur @Component dans la base de code TypeDoc.
@Le décorateur de composants est importé de lib/utils/components.ts
Il s'agit d'une fabrique de décorateurs qui renvoie une fonction de flèche exécutée au moment de l'exécution. Vous pouvez en savoir plus sur Decorator Factory dans la documentation 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; } } }; }
Il se passe beaucoup de choses dans ce décorateur de composants, au lieu d'essayer de tout comprendre, reprenons les plus faciles que nous pouvons en déduire.
Cette vérification est utilisée pour générer une erreur au cas où l'instance ne serait pas prise en charge.
2. proto.componentName
proto.componentName est mis à jour en fonction du nom transmis au décorateur. Dans ce cas, le nom est défini sur « application ».
3. mappages d'enfants
// 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; } }
Des mises à jour ont été apportées à childMapping.host
Chez Think Throo, nous avons pour mission d'enseigner les concepts architecturaux avancés de base de code utilisés dans les projets open source.
10x vos compétences en codage en pratiquant des concepts architecturaux avancés dans Next.js/React, apprenez les meilleures pratiques et créez des projets de niveau production.
Nous sommes open source — https://github.com/thinkthroo/thinkthroo (Donnez-nous une étoile !)
Nous fournissons également des services de développement Web et de rédaction technique. Contactez-nous à [email protected] pour en savoir plus !
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
Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.
Copyright© 2022 湘ICP备2022001581号-3