2016-01-06 52 views
8

在此代碼中,我試圖讓用戶指定通用裝飾器函數fetchJson的類型。在Typescript中創建泛型方法裝飾器

它的工作是這樣的:

  1. 裝飾用類似的方法:@fetchJson<User>
  2. 然後,我們更換一個自動調用.then(res => res.json())的功能,並給回裹在無極特定類型的值。

我遇到的問題是,我不知道怎麼回descriptor.value到用戶指定的T. 是否有更好的方法來做到這一點的工作?我覺得我完全錯過了一些東西。

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'. 

回答

7

也許是這樣的:

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) 
    { 
     //.... 
    } 
}