2017-09-18 1 views
0

J'ai un décorateur pour les méthodes que je veux qu'il ne soit utilisé qu'avec des méthodes asynchrones. Ceci est un exemple d'utilisation:Restreindre l'utilisation des décorateurs de méthode

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

J'ai essayé de définir le décorateur comme celui-ci:

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

Mais cela ne fonctionne pas. Il échoue dans les deux méthodes works et fails parce que le K[K in keyof T] et K dans K extends string et propertyKey: K ne sont pas les mêmes, donc le K ne se limite pas à être une clé de T.

Cela ne fonctionne pas non plus:

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

Ni ceci:

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

Toute idée?

Répondre

1

Vous devez utiliser un décorateur de méthode, pas un décorateur de propriété:

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

Un décorateur qui peut être ajouté à toute méthode de retour d'une promesse serait:

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

échantillon modifié de here

+0

Quel était exactement le problème? Utilisation de PropertyDescriptor au lieu de TypedPropertyDescriptor? – lilezek

+0

'PropertyDecorator' n'offre pas un moyen de restreindre en fonction du type de la cible,' MethodDecorator' est une méthode générique et le type générique est le type de la cible. Généralement, puisque vous décorez une méthode, vous devriez utiliser le 'MethodDecorator' comme son nom l'indique –