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

时间:2016-11-07 14:22:51

标签: angular typescript

如果我用自己的装饰器装饰一个Component,我怎么让TypeScript知道我已经通过@MyComponentDecorator

向该类添加了功能(方法)
@Component({
    selector: 'MySelector',
    template: 'bar'

})
@MyComponentDecorator
export class MyClass {

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

问候

肖恩

2 个答案:

答案 0 :(得分:4)

您可以设置具有相同名称的界面:

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

有了这个:

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

修改

您可以使用类实现接口,但是您需要执行此操作:

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

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

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

code in playground

如果您不添加myNewMethod作为属性,则会抱怨:

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

答案 1 :(得分:0)

这里的Tx到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')
            }
        );
    }

}