この記事では、TypeDoc のコンポーネント デコレータを分析します。
一歩下がって、まず TypeScript のデコレーターとは何かを理解しましょう。
A Decorator は、クラス宣言、メソッド、アクセサー、プロパティ、またはパラメーターに添付できる特別な種類の宣言です。デコレーターは @expression 形式を使用します。expression は、装飾された宣言に関する情報を使用して実行時に呼び出される関数として評価される必要があります。 - ソース。
たとえば、デコレータ @sealed を指定すると、sealed 関数を次のように記述できます:
function sealed(target) { // do something with 'target' ... }
クラス デコレーターの使用方法について、TypeScript ドキュメントからシンプルでわかりやすい例を選択してみましょう。
@sealed class BugReport { type = "report"; title: string; constructor(t: string) { this.title = t; } }
ここで @sealed は、クラス宣言のすぐ上に適用されるクラス デコレータです。この @sealed は実行時に適用されるデコレーターです。
クラス BugReport への変更を防ぎたい場合は、次のようにシールされた関数を定義できます:
function sealed(constructor: Function) { Object.seal(constructor); Object.seal(constructor.prototype); }
@sealed が実行されると、コンストラクターとそのプロトタイプの両方がシールされるため、実行時に BugReport.prototype にアクセスしたり、BugReport 自体のプロパティを定義したりすることによって、このクラスに機能が追加または削除されるのを防ぎます。ソース
この知識により、TypeDoc コード ベースの @Component デコレーターを理解する準備が整いました。
@Component デコレータは lib/utils/components.ts
からインポートされますこれは、実行時に実行されるアロー関数を返すデコレータ ファクトリです。デコレータ ファクトリの詳細については、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; } } }; }
このコンポーネント デコレータでは多くのことが行われています。すべてを理解しようとするのではなく、推定できる簡単なものを取り上げてみましょう。
このチェックは、インスタンスがサポートされていない場合にエラーをスローするために使用されます。
2.プロト.コンポーネント名
proto.componentName は、デコレーターに渡された名前に基づいて更新されます。この場合、名前は「アプリケーション」となります。
3.子マッピング
// 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; } }
childMapping.host にいくつかの更新が行われました
Think Throo では、オープンソース プロジェクトで使用される高度なコードベース アーキテクチャの概念を教えることを使命としています。
Next.js/React の高度なアーキテクチャ概念を実践してコーディング スキルを 10 倍にし、ベスト プラクティスを学び、本番レベルのプロジェクトを構築します。
私たちはオープンソースです — https://github.com/thinkthroo/thinkthroo (スターを付けてください!)
また、ウェブ開発およびテクニカル ライティング サービスも提供しています。詳細については、[email protected] までお問い合わせください。
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
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3