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

TypeScript中使用联合类型变量时能否获知对象的确切类型?

核心原因

你运行console.log(typeof c)输出object是正常结果,本质原因有两个:

  • TypeScript的类型系统仅在编译阶段生效:所有接口、类型标注、联合类型这些TS专属的语法,在编译为JavaScript运行时都会被完全擦除,JS运行环境根本感知不到你定义过Car、Bike这两个接口,自然不可能返回对应的类型名称。
  • typeof是JavaScript原生的运行时操作符:它本身就只能识别JS内置的基础类型,返回值只有string/number/boolean/undefined/object/function/symbol/bigint这几种,对于自定义结构的对象,统一返回object,不具备识别自定义结构类型的能力。

补充一点你这段代码的编译时逻辑:TS是结构化类型系统,只要结构满足接口要求就判定类型匹配,你赋值的{gears: 2}完全符合Car接口的定义(缺少Bike接口要求的必填model字段,不可能是Bike),所以编译阶段TS其实能判定此时c的类型是Car,但这个判断结果不会留存到运行阶段。

运行时区分联合类型的实现方式

由于TS的类型擦除特性,要在运行时判断联合类型的具体成员,需要手动实现类型守卫,针对你的场景有两种常用方案:

1. 添加判别式字段(推荐)

给两个接口增加一个值为字面量类型的专属标记字段,运行时直接判断这个字段的值即可,TS也能基于这个判断自动做编译时的类型收窄:

interface Car {
  kind: 'car'
  gears: number
}

interface Bike{
  kind: 'bike'
  gears: number,
  model: string
}

let c: Bike | Car;
c = {kind: 'car', gears : 2};

if (c.kind === 'car') {
  // 此处TS自动将c收窄为Car类型
  console.log('当前变量是Car')
} else {
  // 此处TS自动将c收窄为Bike类型,可以直接访问model属性
  console.log('当前变量是Bike,型号为:', c.model)
}

2. 判断独有属性是否存在

你的两个接口里,Bike存在独有的model字段,Car没有这个字段,可以用in操作符判断属性是否存在来区分类型:

let c: Bike | Car;
c = {gears : 2};

if ('model' in c) {
  // 收窄为Bike
  console.log('当前变量是Bike')
} else {
  // 收窄为Car
  console.log('当前变量是Car')
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 06:06:56