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
相关产品推荐
相关产品推荐

