简体   繁体   English

如何通过类/组件装饰器让TypeScript知道添加的方法?

[英]How to let TypeScript know of added methods via class / component decorator?

If I am decorating a Component with my own decorator, how do I let TypeScript know that I have added functionality (methods) to that class via @MyComponentDecorator 如果我使用自己的装饰器装饰Component,如何让TypeScript知道我已通过@MyComponentDecorator向该类添加了功能(方法)

@Component({
    selector: 'MySelector',
    template: 'bar'

})
@MyComponentDecorator
export class MyClass {

    constructor(){
         this.myNewMethod('foo'); // TypeScript error as transpiler is not aware
    }
}
 ...

regards 问候

Sean 肖恩

You can set up an interface with the same name: 您可以使用相同的名称设置接口:

interface MyClass {
    myNewMethod(str: string): void;
}

With this: 有了这个:

function MyComponentDecorator(constructor: { new (): MyClass }) {
    constructor.prototype.myNewMethod = function (str: string) {
        console.log(str);
    }
}

interface MyClass {
    myNewMethod(str: string): void;
}

@MyComponentDecorator
class MyClass {
    constructor() {
         this.myNewMethod('foo');
    }
}

( code in playground ) 操场上的代码


Edit 编辑

You can implement the interface with the class, but then you need to do this: 您可以使用该类实现该接口,但是您需要这样做:

interface IMyClass {
    myNewMethod(str: string): void;
}

@MyComponentDecorator
class MyClass implements IMyClass {
    constructor() {
         this.myNewMethod('foo');
    }

    myNewMethod: (str: string) => void;
}

( code in playground ) 操场上的代码

If you don't add myNewMethod as property then it complains that: 如果不将myNewMethod添加为属性,则它会抱怨:

this.myNewMethod('foo'); // Error: Property 'myNewMethod' does not exist on type 'MyClass'

Tx to Tomer here is the final solution (beware as its not compatible with Angular AOT mode): Tx to Tomer是最终的解决方案(请注意,它与Angular AOT模式不兼容):

export function TakeUntilDestroy(constructor) {
    var original = constructor.prototype.ngOnDestroy;
    var subject;
    var unsub;
    constructor.prototype.componentDestroy = function () {
        subject = new Subject();
        return subject.asObservable();
    };
    constructor.prototype.unsubOnDestroy = function (i_unsub) {
        unsub = i_unsub;
    };
    constructor.prototype.ngOnDestroy = function () {
        original && typeof original === 'function' && original.apply(this, arguments);
        unsub === 'function' && unsub();
        subject && subject.next('ngOnDestroy') && subject.unsubscribe();
    };
}


export interface AdnetConfigTargets {
    unsubOnDestroy(i_value:Function): void;
}

@Component({
    selector: 'AdnetConfigTargets',
    moduleId: __moduleName,
    template: AdnetConfigTargetsTemplate

})
@TakeUntilDestroy
export class AdnetConfigTargets {

    constructor(private appStore: AppStore) {}

    ngOnInit() {

        this.unsubOnDestroy(()=>{
                console.log('do something when Component is destroyed')
            }
        );
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM