2016-01-06 14 views
8

In questo codice, sto provando ad avere un utente che specifica un tipo per la funzione di decoratore generica fetchJson.Creazione di un decoratore di metodi generici in Typescript

Funzionerebbe così:

  1. Decorare un metodo con qualcosa di simile: @fetchJson<User>
  2. Abbiamo poi sostituiamo la funzione con quella che chiama automaticamente .then(res => res.json()), e restituiamo un valore digitato avvolto in una promessa.

L'edizione che sto funzionando in è che non so come assegnare il ritorno descriptor.value ad un T. assegnato dall'utente C'è un modo migliore per fare questo? Mi sento come se mi mancasse qualcosa completamente.

interface PromiseDescriptorValue<T>{ 
    (...args: any[]): Promise<T>; 
} 

const fetchJson = <T>(
    target: Object, 
    propertyKey: string, 
    descriptor: TypedPropertyDescriptor<PromiseDescriptorValue<Response>> // Response is a whatwg-fetch response -- https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/whatwg-fetch/whatwg-fetch.d.ts#L58 
): TypedPropertyDescriptor<PromiseDescriptorValue<T>> => { 
    const oldMethod = descriptor.value; 

    descriptor.value = function(...args: any[]) { 
    return oldMethod.apply(this, args).then((res: Response) => res.json()); 
    }; 

    return descriptor; 
}; 


// TS2322: Type 'TypedPropertyDescriptor<PromiseDescriptorValue<Response>>' 
// is not assignable to type 
// 'TypedPropertyDescriptor<PromiseDescriptorValue<T>>'. Type 
// 'PromiseDescriptorValue<Response>' is not assignable to type 
// 'PromiseDescriptorValue<T>'. Type 'Response' is not assignable to type 'T'. 

risposta

7

Forse qualcosa di simile:

interface PromiseDescriptorValue<T>{ 
    (...args: any[]): Promise<T>; 
} 

export function fetchJson<T>(): any 
{ 
    return (
     target: Object, 
     propertyKey: string, 
     descriptor: any): TypedPropertyDescriptor<PromiseDescriptorValue<T>> => 
     { 
     const oldMethod = descriptor.value; 

     descriptor.value = function(...args: any[]) 
     { 
      return oldMethod.apply(this, args).then((res: Response) => res.json()); 
     }; 

     return descriptor; 
     }; 
} 

class C 
{ 
    @fetchJson<User>() 
    foo(args) 
    { 
     //.... 
    } 
}