2017-09-18 49 views
0

我有一個裝飾器方法,我希望它只能用於異步方法。這是使用的例子:限制方法裝飾器的使用

class A { 
    @deco() // This should work. 
    public async works() { } 
    @deco() // This should fail. 
    public fails() { } 
} 

我試圖這樣定義裝飾:

export function deco() { 
    return <T extends {[K in keyof T]:() => Promise<any>}, 
      K extends string> 
     (target: T, 
      propertyKey: K, 
      descriptor: PropertyDescriptor) => { 
    // Decorator code here. 
    }; 
} 

但它不工作。它未能在這兩個worksfails方法,因爲K[K in keyof T]K extends stringpropertyKey: KK是不一樣的,因此K並不限定爲T.

的關鍵這不起作用或者:

export function deco() { 
    return <T extends {[K in keyof T]:() => Promise<any>}, 
      K extends keyof T> 
     (target: T, 
      propertyKey: K, 
      descriptor: PropertyDescriptor) => { 
    // Decorator code here. 
    }; 
} 

無論是這樣的:

export function deco() { 
    return <T, 
      K extends keyof T> 
     (target: T & {[propertyKey]:() => Promise<any>}, 
      propertyKey: K, 
      descriptor: PropertyDescriptor) => { 
    // Decorator code here. 
    }; 
} 

任何想法?

回答

1

您應該使用的方法裝飾,而不是物業裝飾:

declare type MethodDecorator = <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void; 

可以添加到返回一個承諾任何方法的裝飾是:從here

修改

function TypeRestrictedMethodDecorator(
    target: Object, // The prototype of the class 
    propertyKey: string, // The name of the method 
    descriptor: TypedPropertyDescriptor<(... p:any[]) => Promise<any>> 
    ) { 
    console.log("TypeRestrictedMethodDecorator called on: ", target, propertyKey, descriptor); 
} 

class TypeRestrictedMethodDecoratorExample { 
    @TypeRestrictedMethodDecorator 
    method(num: number): Promise<number> { 
     return new Promise((res, rej)=> res(10)); 
    } 

    @TypeRestrictedMethodDecorator // Error 
    method2(num: number): number { 
     return 10; 
    } 
} 

樣品

+0

究竟是什麼問題?使用PropertyDescriptor而不是TypedPropertyDescriptor? – lilezek

+0

「PropertyDecorator」沒有提供基於目標類型進行限制的方式,「MethodDecorator」是通用方法,泛型類型是目標類型。一般來說,因爲你正在裝飾一個方法,所以你應該使用一個'MethodDecorator'顧名思義 –