2017-09-18 50 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'顾名思义 –