В этой статье мы анализируем декоратор Component в TypeDoc.
Давайте сделаем шаг назад и сначала разберемся, что такое декоратор в TypeScript.
Декоратор — это особый вид объявления, которое можно прикрепить к объявлению класса, методу, методу доступа, свойству или параметру. Декораторы используют форму @expression, где выражение должно возвращать функцию, которая будет вызываться во время выполнения с информацией об декорированном объявлении. - Источник.
Например, учитывая декоратор @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 — Источник
Обладая этими знаниями, мы теперь готовы понять декоратор @Component в базе кода TypeDoc.
Декоратор @Component импортируется из lib/utils/comComponents.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.comComponentName обновляется на основе имени, переданного декоратору. В данном случае в качестве имени установлено «приложение».
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 мы стремимся обучать передовым архитектурным концепциям кодовой базы, используемым в проектах с открытым исходным кодом.
Увеличьте свои навыки программирования в 10 раз, практикуя передовые архитектурные концепции в Next.js/React, изучайте лучшие практики и создавайте проекты промышленного уровня.
У нас открытый исходный код — 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/comComponent.ts#L39
https://www.typescriptlang.org/docs/handbook/decorators.html#decorator-factories
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3