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

仅指定单个泛型参数时,如何让后续泛型参数自动推导?

问题:指定部分泛型参数时自动推导剩余泛型

在TypeScript中定义了如下代码:

interface Option<T> {
  on: (p: T) => T
}

function identity<A, B = any> (a: A, b: B, c?: Option<B>) {}

// 不指定泛型时,p能正确推导为{a: 1}
identity(1,
  {
    a: 1
  },
  {
    on: p => p
  }
)

// 仅指定泛型A时,p被推导为any
identity<number>(1,
  {
    a: 1
  },
  {
    on: p => p
  }
)

请问当仅指定泛型A时,有没有办法让泛型B根据传入的参数b自动推导?我自己想到了一个柯里化的方案,但侵入性较强:

function identity<A> (a: A) {
  return <B>(b: B, c?: Option<B>) => {}
}

identity<number>(1)({ a: 1 }, { on: p => p })

解答

这是因为TypeScript的泛型推断规则:当你显式指定了部分泛型参数时,剩余未指定的参数会直接使用它们的默认值(这里B的默认值是any),不会再从函数参数里自动推导。下面提供几种可行的解决方法:

1. 柯里化拆分(你的方案)

把函数拆分成两次调用,第一次指定A并接收参数a,第二次让TypeScript自动推导B。这种方式虽然改变了调用方式,但逻辑清晰,是处理部分泛型推导的常用手段,尤其在TS版本较低时很实用。

2. TypeScript 4.7+ 部分泛型参数推断

从TypeScript 4.7开始,支持用_作为泛型参数的占位符,告诉编译器“这个参数帮我自动推导”,完全不需要修改原函数结构:

identity<number, _>(1,
  {
    a: 1
  },
  {
    on: p => p // 此时p能正确推导为{a: 1}
  }
)

这个方案侵入性最低,直接在调用时用_代替需要自动推导的泛型参数即可。

3. 调整泛型默认值(兜底方案)

如果无法升级TS版本,也可以修改函数的泛型默认值,让B的默认值从参数b的类型推断,写法稍复杂但能兼容旧版本:

type InferFromArg<T> = T extends undefined ? any : T
function identity<A, B = InferFromArg<typeof b>>(a: A, b: B, c?: Option<B>) {}

不过这种方式不如前两种直观,优先级低于前两个方案。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 12:55:02