You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 08:25:57