Home > database >  Transform return type of all function in the class while preserve generic
Transform return type of all function in the class while preserve generic

Time:12-02

I'm finding a way to transform the return type of all functions in the class.
While it needs to preserve generic.

Given a MyService class

class CustomPromise<T> extends Promise<T> {
  customData: string;
}

interface RespSomething {
  data: string;
}

interface RespWhatever {
  data: number;
}

class MyService {
  something(req: { x: string; y: string }): CustomPromise<RespSomething> {
    return new CustomPromise<RespSomething>((res, req) => {});
  }

  whatever(req: { a: string }): CustomPromise<RespWhatever> {
    return new CustomPromise<RespWhatever>((res, req) => {});
  }
}

I want to transform the type into

interface TransformedMyService {
  something(req: { x: string; y: string }): Promise<RespSomething>;
  whatever(req: { a: string }): Promise<RespWhatever>;
}

I scratched my head around.
Is this even possible in typescript?

CodePudding user response:

This can be done via a mapped type where you use conditional type inference to extract the method argument types and the type argument for CustomPromise<T>:

type TransformedMyService = { [K in keyof MyService]:
  MyService[K] extends { (...args: infer A): CustomPromise<infer R> } ?
  { (...args: A): Promise<R> } :
  MyService[K]
}

Which results in:

/*
type TransformedMyService = {
    something: (req: {
        x: string;
        y: string;
    }) => Promise<RespSomething>;
    whatever: (req: {
        a: string;
    }) => Promise<RespWhatever>;
}
*/

as desired.

Playground link to code

  • Related