限制方法装饰器的使用

时间:2017-09-18 13:48:19

标签: typescript generics decorator

我有一个方法的装饰器,我希望它只用于异步方法。这是一个使用示例:

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]KK extends string中的propertyKey: K不是同样,因此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 个答案:

答案 0 :(得分:2)

你应该使用方法装饰器,而不是属性装饰器:

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

可以添加到任何返回promise的方法的装饰器将是:

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;
    }
}

here

修改的示例