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

TypeScript空对象类型{}覆盖泛型函数返回类型的原因

类型推导结果不符合预期的核心原因

你对{}的语义理解是准确的:它确实代表所有非null、非undefined的合法值,是TypeScript内置的顶层类型之一。

出现推导结果和预期不符,本质是TypeScript在做联合类型归一化处理时的固有规则+设计取舍:

  • 联合类型会自动剔除被其他成员完全覆盖的子类型:只要类型A的所有合法取值都属于类型B的取值范围,A | B就会被直接简化为B。
  • 对于没有显式添加约束的泛型T,TS在推导函数返回值阶段会判定:所有非null、非undefined的T取值,都完全属于{}的覆盖范围;而无约束泛型默认不会被特殊标记为可能携带null/undefined分支,因此T | {}会被直接简化收敛为{}。

验证方式

只要给泛型T显式加上包含null/undefined的约束,让T的取值范围存在{}覆盖不到的部分,推导结果就会符合最开始的预期:

const func = <T extends null | undefined | string>(arg: T) => {
    if (Math.random() < 0.5) {
        return arg
    }
    return {}
}
// 此时推导类型为:<T extends null | undefined | string>(arg: T) => T | {}

额外说明

这种收敛是TS为了避免泛型推导产生过于复杂的类型做的设计取舍,本身不是100%类型安全的:如果你给示例中无约束的func传入null/undefined作为参数,运行时确实有概率返回传入的null/undefined,但类型层面会被错误推导为{},丢失null/undefined的类型信息。这也是为什么lint规则不推荐在代码中随意使用{}类型,它很容易在隐式推导中造成类型边界模糊,掩盖潜在的类型问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 20:24:28