Creating a universal method decorator in Typescript

In this code, I am trying to tell the user the type of the universal function fetchJson.

It will work as follows:

  • Decorate the method with something like: @fetchJson<User>
  • Then we replace the function with one that automatically calls .then(res => res.json()) , and returns the typed value enclosed in Promise back.

The problem I am facing is that I do not know how to assign return descriptor.value assigned by user T. Is there a better way to do this? I feel like I'm missing something completely.

 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'. 
+8
generics types decorator typescript
source share
1 answer

Maybe something like this:

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

All Articles