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

TypeScript多泛型自动推断:两种写法为何表现不同?

TypeScript泛型推断差异的原因解析

问题场景

你尝试通过extends关键字让TypeScript自动推断第二个泛型类型,第一种写法报错要求指定第二个泛型,而柯里化后的写法却能自动推断:

第一种写法(报错)

function b<T, U extends Partial<T>>(u: U) {
    return u
} 

b<User>({name: 'string'}) // 提示:expected 2 type arguments, but got 1

第二种写法(正常推断)

function b<T>() {
    return function<P extends Partial<T>>(p: P) {
        return p
    }
}

b<User>()({name: 'string'}) // 自动推断P的类型

核心原因

1. 同一层级泛型的限制

第一种写法中,T和U是同一层级的泛型参数。TypeScript的规则是:当你手动指定部分泛型参数时,必须显式指定所有泛型参数——哪怕其中一个的约束依赖于另一个。

虽然U的约束U extends Partial<T>依赖于T,但编译器不会在你只传T的情况下,自动根据函数参数去推断U。它不支持“混合指定+推断”的模式(TypeScript 4.7+支持用_占位符实现部分推断,比如b<User, _>({name: 'string'}),但这是语法糖,并非默认行为)。

2. 柯里化拆分泛型阶段

第二种写法通过柯里化把函数拆成两层,将泛型参数的处理分成了两个独立阶段:

  • 第一阶段调用b<User>()时,你显式固定了T的类型,此时内层函数的约束P extends Partial<T>已经有了明确的依赖基准。
  • 第二阶段调用内层函数时,编译器可以单独根据传入的参数{name: 'string'},反向推断出符合Partial<User>约束的P类型——因为此时T已经确定,P的推断不再依赖未指定的泛型,完全可以自动完成。

简单来说,柯里化把相互依赖的泛型参数拆到不同层级,让编译器可以分阶段处理:先固定上层泛型,再自动推断下层泛型,完美避开了同一层级泛型的“全指定或全推断”限制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.01 13:04:53