是否可以在 Typescript 中装饰装饰器?

Posted

技术标签:

【中文标题】是否可以在 Typescript 中装饰装饰器?【英文标题】:Is it possible to decorate a decorator in Typescript? 【发布时间】:2016-09-11 13:53:40 【问题描述】:

构建一个组件库,@Component 装饰器中有相当多的样板。例如样式和模板 url 总是相同的相对路径。想知道是否可以使用装饰器将其干燥。

我想我可以编写一个复制 @Component 功能的那些部分的装饰器,但我希望利用已经存在的东西。

【问题讨论】:

【参考方案1】:

您当然可以扩展组件功能并抽象一些功能, 下面是基于Extending component decorator with base class decorator的解决方案

component-metadata.ts

    import "reflect-metadata";
    import  ComponentMetadata  from "@angular/core";

    export function MyComponent(annotation: any): any 
      return function (target: Function) 
         let parentTarget = Object.getPrototypeOf(target.prototype).constructor;
         let parentAnnotations = Reflect.getMetadata("annotations", parentTarget);

         let parentAnnotation = parentAnnotations[0];
         Object.keys(parentAnnotation).forEach(key => 
           if (isPresent(parentAnnotation[key])) 
              annotation[key] = parentAnnotation[key];
           
        );

        let fileName: string = annotation.moduleId.substring(0, annotation.moduleId.lastIndexOf("."));
        annotation["templateUrl"] = fileName + ".html";
        annotation["styleUrls"] = [fileName + ".css"];        
        let metadata: ComponentMetadata = new ComponentMetadata(annotation);

        Reflect.defineMetadata("annotations", [metadata], target);
     
   

假设 html 和 css 与组件定义在同一个文件夹中并且具有相同的名称,您可以根据需要进行更新。 例如

html : some.component.html

css : some.component.css

some.component.ts

   @MyComponent(
     selector: "some-component",
     moduleId: module.id 
   )
   export class SomeComponent
      // Class implementation
   

【讨论】:

太棒了!感谢您提供详细的示例。

以上是关于是否可以在 Typescript 中装饰装饰器?的主要内容,如果未能解决你的问题,请参考以下文章

TypeScript 箭头函数和装饰器

Python编程系列---Python中装饰器的几种形式及万能装饰器

在类中装饰 @property.setter 装饰器 [重复]

在 MRO 中装饰顶部功能

Decorators装饰器——TypeScript

TypeScript装饰器(decorators)