You need to enable JavaScript to run this app. 为什么TypeScript中对象的类型会提前解析为联合类型的单侧分支
优惠活动
大模型
产品
解决方案
定价
更多

为什么TypeScript中对象的类型会提前解析为联合类型的单侧分支

类型推导结果的核心原因

前置推导前提

该场景下的推导结果,是TypeScript静态控制流分析(类型收窄)机制的标准表现,完全符合语言规范的推导规则:

  • 示例中的Foo、Bar两个接口属于典型的可辨识联合类型,二者都带有字面量类型的kind判别属性:Foo的kind为固定字面量'foo',Bar的kind为固定字面量'bar'
  • 进入对应代码行面前,obj的初始静态类型为Foo | Bar

第18行位置的收窄逻辑

当代码进入if (obj.kind !== 'bar')判断的真分支块内部时,TypeScript会自动对obj执行反向类型收窄。收窄的计算规则为:遍历联合类型的所有成员,剔除所有不满足当前分支判断条件的类型,仅将满足条件的类型作为当前位置的可能类型集合:

  • 遍历到Bar类型时,由于Bar的kind是固定字面量'bar',天生满足obj.kind === 'bar',与当前分支“kind不等于'bar'”的条件完全冲突,会被从可能的类型集合中完全剔除
  • 遍历到Foo类型时,由于Foo的kind是固定字面量'foo',天生满足obj.kind !== 'bar'的分支条件,会被保留在可能的类型集合中
    经过上述计算,分支块内部obj的可能类型集合就只剩下Foo,并不会保留初始的Foo | Bar联合类型,这也是观测到“第18行obj已经被解析为Foo类型”的直接原因。

第19行obj被推导为never的原因

在上述已经被收窄为Foo的类型基础上,代码继续执行obj.kind === 'bar'的判断时,TypeScript会再次执行相同的收窄计算:

  • 当前obj的静态类型为Foo,其kind属性是固定的'foo'字面量,从静态类型层面就永远不可能满足kind === 'bar'的判断条件
  • 满足该分支判断条件的可能类型集合为空,类型系统中空集合对应的类型即为never。

常见认知误区

对该推导结果的困惑,大多来自对机制的认知偏差,核心是混淆了编译期静态类型推导与运行时动态判断的边界:TypeScript的类型收窄不会等待代码实际运行后再判定类型,所有推导都基于编译期已知的类型信息完成,只要从静态类型层面能推导出某个分支永远不可能被触发,对应位置的变量类型就会被标记为never。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.04 07:15:09