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

TypeScript中定义互斥组合类型后属性访问报错,问题出在哪?

TypeScript 联合交叉类型访问报错的原因与解决方案

错误原因

你定义的system_info本质是(base_info & week_info) | (base_info & workout_info),但因为week_info和workout_info的属性都是可选的,初始化时仅传入base_info属性的对象同时符合两个分支的类型。TypeScript的类型检查规则是:访问联合类型的属性时,只能访问所有分支共有的属性。days_selected只存在于base_info & week_info分支,不存在于另一个分支,所以直接访问会触发报错。

解决方案

方案1:添加类型标识(推荐)

给两个分支类型添加唯一的类型字段,让TypeScript能明确区分对象属于哪个分支:

type base_info = {
  id?: number,
  name: string,
  email: string
}

// 添加type字段作为区分标识
type week_info = {
  type: 'week',
  days_selected?: string[]
}

type workout_info = {
  type: 'workout',
  workout_intensity?: number
}

type system_info = (base_info & week_info) | (base_info & workout_info)

使用时通过类型守卫判断分支,即可安全访问对应属性:

const check: system_info = {
  type: 'week',
  name: "Billy",
  email: "abc@gmail.com"
}

// 类型守卫明确当前分支
if (check.type === 'week') {
  check.days_selected = ["Monday"] // 无报错
}

方案2:实现互斥属性(无需额外标识)

通过条件类型实现属性互斥,确保对象不能同时拥有days_selected和workout_intensity,同时通过属性存在判断做类型守卫:

type base_info = {
  id?: number,
  name: string,
  email: string
}

type week_info = {
  days_selected?: string[]
}

type workout_info = {
  workout_intensity?: number
}

// 实现属性互斥的工具类型
type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never };
type XOR<T, U> = (T | U) extends object ? (Without<T, U> & U) | (Without<U, T> & T) : T | U;

type system_info = base_info & XOR<week_info, workout_info>

使用时通过in操作符判断属性是否存在:

const check: system_info = {
  name: "Billy",
  email: "abc@gmail.com"
}

if ('days_selected' in check) {
  check.days_selected = ["Monday"] // 无报错
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 23:02:34