TypeScript中两种泛型函数类型的相互转换方法问询
两种泛型函数类型的相互转换方案
你提到的两种泛型函数类型本质上是泛型函数(Foo,泛型参数绑定在函数本身)和参数化函数类型(Bar,泛型参数绑定在类型构造器)的区别:前者使用ReturnType时会返回unknown,后者传入具体类型后能得到明确的返回值类型。以下是两种类型的相互转换方案:
1. 从泛型函数(Foo)转换为参数化函数类型(Bar)
定义一个泛型类型构造器,接收具体类型参数S,返回对应签名的函数类型:
type Foo = <S>(a: S) => S; // 转换工具:将Foo转换为Bar形式的参数化类型 type FooToBar<S> = Foo extends <T>(a: T) => infer R ? (a: S) => (R extends T ? S : never) : never; // 验证效果 type FooToBarString = FooToBar<string>; // 类型为 (a: string) => string type FooToBarReturnType = ReturnType<FooToBar<string>>; // 类型为 string
这个转换通过条件类型推断原泛型函数的参数和返回值关联,将泛型参数T替换为具体类型S,最终得到和Bar<string>完全一致的函数类型。
2. 从参数化函数类型(Bar)转换为泛型函数(Foo)
将参数化类型转换为泛型函数类型,让函数本身拥有泛型参数:
type Bar<S> = { (a: S): S }; // 转换工具:将Bar转换为Foo形式的泛型函数 type BarToFoo = <S>(a: S) => Bar<S> extends (a: S) => infer R ? R : never; // 验证效果 type BarToFooReturnType = ReturnType<BarToFoo>; // 类型为 unknown,和Foo的ReturnType结果一致
这里通过定义一个泛型函数,将类型参数S传递给Bar<S>并提取其返回值类型,最终得到和Foo完全一致的泛型函数类型。
通用化扩展
如果你的泛型函数有多个参数或更复杂的签名,可调整转换逻辑适配:
// 示例:多参数泛型函数 type Baz = <T, U>(a: T, b: U) => [T, U]; // 转换为参数化类型 type BazToParametric<T, U> = Baz extends <A, B>(a: A, b: B) => infer R ? (a: T, b: U) => (R extends [A, B] ? [T, U] : never) : never; type BazStringNumber = BazToParametric<string, number>; // (a: string, b: number) => [string, number]
内容的提问来源于stack exchange,提问作者TrevTheDev
相关产品推荐
相关产品推荐

