给定一个重载函数和参数类型,在Typescript中找到返回类型?



根据这个答案(https://stackoverflow.com/a/52761156/599184),ReturnType<>一般不能与重载函数一起工作。但是,是否有可能选择重载函数的特定版本并获得其返回类型?

我能想到的唯一方法是让代码调用重载的函数。

function fn(arg: string): string;
function fn(arg: number): number;
function fn(arg: string | number): string | number {
return arg;
}
const temp1 = () => fn('string');
type Type1 = ReturnType<typeof temp1>; // string
const temp2 = () => fn(123);
type Type2 = ReturnType<typeof temp2>; // number

TS操场

有没有一种更简洁的方法,我不需要传递参数(只是参数类型)?

通过组合获取参数的类型和获取返回类型的类型,我们可以创建一个获得重载的类型:

type _Overloads<T> = 
T extends { (...args: infer A1) : infer R1; (...args: infer A2) : infer R2; (...args: infer A3) : infer R3; (...args: infer A4) : infer R4 } ? [[A1, R1], [A2, R2], [A3, R3], [A4, R4]] :
T extends { (...args: infer A1) : infer R1; (...args: infer A2) : infer R2; (...args: infer A3) : infer R3 } ? [[A1, R1], [A2, R2], [A3, R3]] :
T extends { (...args: infer A1) : infer R1; (...args: infer A2) : infer R2 } ? [[A1, R1], [A2, R2]] :
T extends (...args: infer A) => infer R ? [[A, R]] : any;

(注意,这只适用于最多四个重载,但您可以扩展它以适用于更多重载)

然后,给定一个重载数组,可以根据实参类型获得返回类型:
type _OverloadsReturnType<O extends [unknown, unknown][], A> = O extends [[A, infer R], ...unknown[]] ? R :
O extends [unknown, ...infer S extends [unknown, unknown][]] ? _OverloadsReturnType<S, A> : any;

最后,创建一个将两者结合的类型:

type OverloadsReturnType<T, A> = _OverloadsReturnType<_Overloads<T>, A>;

像这样使用:

type ret1 = OverloadsReturnType<typeof fn, [string]>;
//   ^?
type ret2 = OverloadsReturnType<typeof fn, [number]>;
//   ^?

(注意^?显示TypeScript Playground中的类型)

TypeScript Playground演示了这一点。

最新更新