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.