Neste artigo, analisamos o decorador de componentes no TypeDoc.
Vamos dar um passo atrás e primeiro entender o que é um decorador no TypeScript.
Um Decorator é um tipo especial de declaração que pode ser anexada a uma declaração de classe, método, acessador, propriedade ou parâmetro. Decoradores usam a forma @expressão, onde expressão deve ser avaliada como uma função que será chamada em tempo de execução com informações sobre a declaração decorada. - Fonte.
Por exemplo, dado o decorador @sealed, podemos escrever a função selada da seguinte forma:
function sealed(target) { // do something with 'target' ... }
Vamos escolher um exemplo simples e fácil de entender da documentação do TypeScript sobre como usar o decorador de classe.
@sealed class BugReport { type = "report"; title: string; constructor(t: string) { this.title = t; } }
Aqui @sealed é um decorador de classe aplicado logo acima da declaração da classe. Este @sealed é um decorador aplicado em tempo de execução.
Se você quiser evitar quaisquer modificações na classe BugReport, você pode definir a função selada conforme abaixo:
function sealed(constructor: Function) { Object.seal(constructor); Object.seal(constructor.prototype); }
Quando @sealed é executado, ele selará tanto o construtor quanto seu protótipo e, portanto, impedirá que qualquer funcionalidade adicional seja adicionada ou removida desta classe durante o tempo de execução acessando BugReport.prototype ou definindo propriedades no próprio BugReport - Fonte
Com esse conhecimento, agora estamos preparados para entender o decorador @Component na base de código TypeDoc.
@Component decorador é importado de lib/utils/components.ts
Esta é uma fábrica de decoradores que retorna uma função de seta que é executada em tempo de execução. Você pode ler mais sobre a fábrica de decoradores nos documentos 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; } } }; }
Há muita coisa acontecendo neste decorador de componentes, em vez de tentar entender tudo, vamos pegar os mais fáceis que podemos deduzir.
Esta verificação é usada para gerar um erro caso a instância não seja suportada.
2. proto.componentName
proto.componentName é atualizado com base no nome passado ao decorador. Neste caso, o nome é definido como “aplicativo”.
3. mapeamentos infantis
// 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; } }
Algumas atualizações foram feitas em childMapping.host
No Think Throo, temos a missão de ensinar os conceitos avançados de arquitetura de base de código usados em projetos de código aberto.
10x suas habilidades de codificação praticando conceitos de arquitetura avançados em Next.js/React, aprenda as melhores práticas e crie projetos de nível de produção.
Somos código aberto - https://github.com/thinkthroo/thinkthroo (Dê-nos uma estrela!)
Nós também fornecemos serviços de desenvolvimento web e redação técnica. Entre em contato conosco em [email protected] para saber mais!
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
Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.
Copyright© 2022 湘ICP备2022001581号-3