TypeScript中能否通过infer推导重载函数的参数?
TypeScript中用infer推导重载函数参数的问题与解决方法
直接通过你提供的代码方式,无法用infer推导重载函数的单个签名参数。原因是TypeScript在处理重载函数的类型extends判断时,会将其视为一个整体的函数类型,而非逐个匹配独立签名。当你写MyFunction extends (key: T, params: infer P) => void时,只有当T能兼容所有重载签名的key类型(即"one" | "two")时,extends判断才会成立,否则直接返回never。
解决方法
要实现根据指定key推导对应参数类型,可以先将重载函数转换为联合类型的单个函数签名,再通过类型筛选提取目标参数:
type MyFunction = { (key: "one", params: { first: string }): void; (key: "two", params: { second: string }): void; } // 将重载函数转换为单个签名的联合类型 type OverloadToUnion<T> = T extends { (...args: infer A): infer R } ? (...args: A) => R : never; // 根据指定key推导对应params类型 type MyFunctionParams<T extends string> = Parameters<Extract<OverloadToUnion<MyFunction>, (key: T, ...args: any[]) => void>>[1]; // 得到 { first: string } type OneParams = MyFunctionParams<"one">; // 得到 { second: string } type TwoParams = MyFunctionParams<"two">;
代码解释
- OverloadToUnion:利用TypeScript的类型推断特性,将重载函数拆分为各个独立签名组成的联合类型,这样就能通过分布式条件类型逐个处理每个签名。
- Extract:从联合类型中筛选出第一个参数为指定
T的函数签名。 - Parameters:获取筛选出的函数的参数数组,取第二个元素即为对应
key的params类型。
如果重载数量较少,也可以直接用枚举式的条件类型实现,虽然灵活性稍差,但更直观:
type MyFunctionParams<T extends "one" | "two"> = T extends "one" ? { first: string } : T extends "two" ? { second: string } : never;
内容的提问来源于stack exchange,提问作者Anatole Lucet
相关产品推荐
相关产品推荐

