TypeScript如何从给定泛型函数推导生成新的自定义泛型函数类型
解决方案
你之前用Parameters和ReturnType丢失泛型的原因是,这两个工具类型作用于未实例化的泛型函数时,会直接将泛型参数解析为其约束的默认值(无约束则为unknown),无法保留动态泛型特性。
最简适配你的示例
针对你给出的givenFunction场景,可以直接通过高阶泛型类型复用原函数的参数和返回值定义,同时保留泛型:
type givenFunction = <T, V>(a: string, b: V) => Promise<T>; // 直接推导生成目标泛型函数类型 type myFunction = <T, V>(b: Parameters<givenFunction<T, V>>[1]) => ReturnType<givenFunction<T, V>>;
验证:你声明const testFn: myFunction = (b) => Promise.resolve(b)后,调用testFn(123)会自动推导返回值为Promise<number>,泛型特性完全保留。
通用封装方案
如果你需要封装任意固定第一个参数的泛型函数,可以写通用的高阶类型复用逻辑:
// 通用封装类型: // 泛型参数1:原泛型函数类型 // 泛型参数2:要固定的第一个参数的类型 type WrapFixedFirstArg< Fn extends <T, V>(first: any, ...rest: any[]) => any, FixedFirstArgType > = <T, V>( // 自动提取去掉第一个参数后的剩余参数类型 ...args: Parameters<Fn<T, V>> extends [FixedFirstArgType, ...infer Rest] ? Rest : never ) => ReturnType<Fn<T, V>>; // 套用你的示例,一行生成目标类型 type myFunction = WrapFixedFirstArg<givenFunction, string>;
注意事项
受TypeScript类型系统限制,目前无法自动提取泛型函数的泛型参数数量、顺序和约束,你需要提前知晓原函数的泛型定义:
- 如果原函数的泛型参数有约束,把通用类型里的
<T, V>替换为和原函数一致的约束即可 - 如果原函数的泛型参数数量不同,调整通用类型里的泛型参数数量即可适配
内容的提问来源于stack exchange,提问作者hollandThomas
相关产品推荐
相关产品推荐

