如何获取任意重载函数的参数类型联合类型?
实现任意数量重载函数的参数类型联合类型
借助TypeScript的递归条件类型,完全可以实现提取任意数量重载函数的参数类型联合(仅受编译器递归深度限制,默认通常为100层)。
核心实现思路
通过递归遍历重载函数的每个签名,逐步提取每一组参数类型,直到遍历完所有重载为止:
// 提取单个重载的参数类型 type GetArgs<T> = T extends (...args: infer A) => any ? A : never; // 递归提取所有重载的参数类型联合 type AllOverloadArgs<T> = T extends { (...args: infer A): any; (...args: infer B): any; } ? A | AllOverloadArgs<OmitFirstOverload<T>> : GetArgs<T>; // 辅助类型:移除第一个重载签名 type OmitFirstOverload<T> = T extends { (...args: infer A): any; (...args: infer B): any; } ? (...args: B) => any : never;
示例验证
比如定义一个有多重重载的函数:
function foo(a: string): void; function foo(a: number, b: boolean): void; function foo(a: string, b: number, c: symbol): void; function foo(...args: any[]) {} // 提取结果:[string] | [number, boolean] | [string, number, symbol] type FooArgs = AllOverloadArgs<typeof foo>;
函数交集类型的情况
重载函数与函数交集的区别
TypeScript中,重载函数类型和多个函数类型的交集并不完全等同:
- 重载函数在调用时会按顺序匹配签名,只有第一个匹配的签名会生效;
- 函数交集类型则允许以任意一个成员函数的签名调用,相当于同时拥有所有签名的调用能力。
函数交集的参数类型提取
对于函数交集类型,同样可以用递归条件类型提取所有参数类型的联合,但处理逻辑略有不同:
// 递归提取函数交集的所有参数类型联合 type AllIntersectionArgs<T> = T extends (...args: infer A) => any ? A | AllIntersectionArgs<Exclude<T, (...args: any) => any>> : never;
示例验证
定义一个函数交集类型:
type Bar = ((a: string) => void) & ((a: number, b: boolean) => void); // 提取结果:[string] | [number, boolean] type BarArgs = AllIntersectionArgs<Bar>;
内容的提问来源于stack exchange,提问作者Glen Whitney
相关产品推荐
相关产品推荐

