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

TypeScript空值合并运算符结果类型的疑问

TypeScript空值合并运算符结果类型的疑问

你提的这个问题其实涉及到TypeScript类型系统里对unknown和空值合并运算符的特殊处理,我来一步步给你拆解:

首先先确认你的代码的类型推断结果:

declare const a: unknown[];
const r = a[3] ?? 'hello'; 
// TypeScript 确实会推断出 const r: {}

你疑惑为什么不是NonNullable<unknown> | string,其实核心原因是:string本身就是NonNullable<unknown>的子类型,而TypeScript里NonNullable<unknown>会被简化为{},所以这两个写法本质上是等价的,TypeScript只是帮你做了冗余类型的合并。

具体来说:

  • 对于a[3],在默认TypeScript配置(未开启noUncheckedIndexedAccess)下,类型是unknown;如果开启了该配置,类型是unknown | undefined,但不管哪种情况,??运算符都会过滤掉null和undefined的情况,取左边的非空类型和右边的string做联合。
  • NonNullable<unknown>表示unknown排除null和undefined后的所有类型,而在TypeScript的类型系统中,这个集合可以被{}类型精准表示——因为{}是所有非null、非undefined值的超类型(包括原始类型如string、number,以及对象、函数等)。
  • 而string本身就属于{}的子类型(你可以验证type IsStringSubsetOfObj = string extends {} ? true : false,结果是true),所以NonNullable<unknown> | string其实完全等价于NonNullable<unknown>,也就是{},TypeScript会自动把这种冗余的联合类型简化为更简洁的{}。

如果想要更直观地看到这个等价关系,可以写几个类型测试:

type NonNullableUnknown = NonNullable<unknown>;
// 类型等价于 {}

type UnionTest = NonNullableUnknown | string;
// 类型等价于 {},因为 string 已经被包含在 NonNullableUnknown 中

所以TypeScript的推断结果是正确的,只是它做了类型简化,把你预期的{} | string合并成了更简洁的{}而已~

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 07:37:57