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

TypeScript中如何描述作为泛型函数调用结果的函数返回类型

正确定义嵌套泛型函数的返回类型

我明白你的问题:你想让foo返回的bar函数,在调用bar<B>()时,返回值类型完全对应fn<B>()的执行结果,但目前TypeScript只能推导到unknown或者Promise<unknown>,根本没法正确识别泛型参数B带来的类型变化。

问题根源

你原来用ReturnType<typeof fn>作为bar的返回类型,这里的问题在于——typeof fn是泛型函数本身,不是传入具体泛型参数后的实例化版本。所以TypeScript只能给你一个最宽泛的默认类型(比如unknown),而不会关联到你调用bar时传入的B。

解决方案:用infer提取泛型函数的实例化返回类型

我们需要让TypeScript明确知道:bar的泛型参数B会传递给fn,并且bar的返回类型就是fn用B作为泛型参数后的返回值。可以通过类型推断(infer)来实现这一点:

function foo<Fn extends <X>() => unknown>(fn: Fn) {
  return function bar<B>(): 
    Fn extends <X>() => infer R ? R : never 
  {
    // 这里需要类型断言,因为TS暂时无法自动推导fn<B>()的类型匹配
    return fn<B>({ /*config*/ }) as ReturnType<typeof fn<B>>;
  }
}

验证示例

现在再跑你原来的测试代码,类型推导就完全符合预期了:

{
  const f1 = <T>() => Promise.resolve(({/*input*/ } as T));
  const x1 = foo(f1)
  const y1 = x1<{ a: 'A' }>()/** 现在推导为Promise<{ a: 'A'}> ✅*/.then(data => data.a); 
  const y12 = x1<{ b: 'B' }>()/** 现在推导为Promise<{ b: 'B'}> ✅*/.then(data => data.b); 
}

{
  const f2 = <T>() => ({/*input*/ } as T);
  const x2 = foo(f2)
  const y2 = x2<{ a: 'A' }>()/** 现在推导为{ a: 'A'} ✅*/.value 
  const y21 = x2<{ b: 'B' }>()/** 现在推导为{ b: 'B'} ✅*/.value 
}

原理说明

  • 我们给foo的类型参数Fn限定为“接收泛型参数X的函数”,这样TypeScript能识别fn的泛型结构。
  • 用Fn extends <X>() => infer R提取出:当fn的泛型参数是X时,返回类型是R。
  • 当bar传入B时,X被替换为B,R就自动变成fn<B>()的返回类型。
  • 最后用as ReturnType<typeof fn<B>>做类型断言,是因为目前TypeScript的类型推导还没法自动关联这一步(这也是相关TS讨论的核心痛点),但这个断言是完全安全的,因为我们逻辑上已经确保了类型匹配。

内容的提问来源于stack exchange,提问作者maksimr

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 02:52:29