I have a requirement to develop a utility type that can take the signature of a generic function along with its arguments. The goal is to determine the return type of the signature as if it were called with those specific arguments.
My initial attempt:
type GetReturnType<T extends (...args: any) => any, B> = T extends (...args: any) => infer R ? R : never;
However, all generics seem to end up being either unknown
or never
.
Here are a few sample functions that might be passed in:
function myFn1<T>(x: T) {
return {
a: x,
}
}
function myFn2<T>(x: T) {
return [x];
}
function myFn3<T>(x: T) {
if (typeof x == "string") {
return "yes" as (T extends string ? "yes" : "no");
} else {
return "no" as (T extends string ? "yes" : "no");
}
}
And here's how I envision using the GetReturnType
:
type Return1 = GetReturnType<typeof myFn1, [x: number]>; // expected {a: number}
type Return2 = GetReturnType<typeof myFn2, [x: number]>; // expected number[]
type Return3A = GetReturnType<typeof myFn3, [x: number]>; // expected "no"
type Return3B = GetReturnType<typeof myFn3, [x: string]>; // expected "yes"
While TypeScript has a mechanism for inferring generic types in functions, such as myFn3("some string")
inferring the first generic argument as a string and returning "yes"
, I would like to leverage this system when determining the return type. Some queries on Stack Overflow discuss achieving this with known generics, but I am interested in doing so with inferred generics.