In diesem Artikel analysieren wir den Component Decorator in TypeDoc.
Gehen wir einen Schritt zurück und verstehen zunächst, was ein Dekorator in TypeScript ist.
Ein Decorator ist eine spezielle Art von Deklaration, die an eine Klassendeklaration, Methode, Accessor, Eigenschaft oder Parameter angehängt werden kann. Dekoratoren verwenden die Form @Ausdruck, wobei Ausdruck zu einer Funktion ausgewertet werden muss, die zur Laufzeit mit Informationen über die dekorierte Deklaration aufgerufen wird. - Quelle.
Angenommen der Dekorator @sealed könnten wir die versiegelte Funktion beispielsweise wie folgt schreiben:
function sealed(target) { // do something with 'target' ... }
Wählen wir ein einfaches und leicht verständliches Beispiel aus der TypeScript-Dokumentation zur Verwendung des Klassendekorators aus.
@sealed class BugReport { type = "report"; title: string; constructor(t: string) { this.title = t; } }
Hier ist @sealed ein Klassendekorator, der direkt über der Klassendeklaration angewendet wird. Dieses @sealed ist ein Dekorator, der zur Laufzeit angewendet wird.
Wenn Sie Änderungen an der Klasse BugReport verhindern möchten, können Sie die versiegelte Funktion wie folgt definieren:
function sealed(constructor: Function) { Object.seal(constructor); Object.seal(constructor.prototype); }
Wenn @sealed ausgeführt wird, versiegelt es sowohl den Konstruktor als auch seinen Prototyp und verhindert daher, dass während der Laufzeit weitere Funktionen zu dieser Klasse hinzugefügt oder daraus entfernt werden, indem auf BugReport.prototype zugegriffen oder Eigenschaften auf BugReport selbst definiert werden – Quelle
Mit diesem Wissen sind wir nun bereit, den @Component-Dekorator in der TypeDoc-Codebasis zu verstehen.
@Component Decorator wird aus lib/utils/components.ts importiert
Dies ist eine Dekoratorfabrik, die eine Pfeilfunktion zurückgibt, die zur Laufzeit ausgeführt wird. Weitere Informationen zur Decorator Factory finden Sie in den TS-Dokumenten.
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; } } }; }
In diesem Komponenten-Dekorator passiert eine Menge. Anstatt zu versuchen, alles zu verstehen, wollen wir uns mit den einfachen Dingen befassen, die wir ableiten können.
Diese Prüfung wird verwendet, um einen Fehler auszulösen, falls die Instanz nicht unterstützt wird.
2. proto.componentName
proto.componentName wird basierend auf dem an den Dekorateur übergebenen Namen aktualisiert. In diesem Fall wird der Name auf „application“ gesetzt.
3. childMappings
// 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; } }
Es wurden einige Aktualisierungen an childMapping.host vorgenommen
Bei Think Throo haben wir es uns zur Aufgabe gemacht, die fortgeschrittenen Codebasis-Architekturkonzepte zu vermitteln, die in Open-Source-Projekten verwendet werden.
Verzehnfachen Sie Ihre Programmierkenntnisse, indem Sie fortgeschrittene Architekturkonzepte in Next.js/React üben, lernen Sie die Best Practices kennen und erstellen Sie Projekte in Produktionsqualität.
Wir sind Open Source – https://github.com/thinkthroo/thinkthroo (Geben Sie uns einen Stern!)
Wir bieten auch Webentwicklung und technische Redaktionsdienste an. Kontaktieren Sie uns unter [email protected], um mehr zu erfahren!
Referenzen:
Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.
Copyright© 2022 湘ICP备2022001581号-3