为什么该示例中的TypeScript类型守卫没有正常生效?
报错根本原因
你定义的SomeType属于无共有属性的非可辨识联合类型,TypeScript 规定:在完成类型收窄之前,你只能访问联合类型所有分支共有的属性,不能直接访问仅存在于单个分支上的属性。
你的代码里直接访问arg.name、arg.age、arg.xy都属于只存在于单个联合分支的属性,TypeScript 无法在类型收窄前确定当前arg属于哪个分支,因此抛出属性不存在的错误。
修复方案
方案1:使用in运算符做类型收窄
这是适配你现有类型定义的最简单修复方式,in运算符可以让TypeScript 准确识别当前的联合分支:
type SomeType = { name: string, age: number, } | { xy: [number, number] } function someFunction(arg: SomeType) { if ('name' in arg && 'age' in arg) { // 此时TS已自动将arg收窄为{name:string, age:number}类型,可正常访问对应属性 // DO STH } else if ('xy' in arg) { // 此时TS已自动将arg收窄为{xy: [number,number]}类型,可正常访问xy属性 // DO STH } }
方案2:将联合类型改造为可辨识联合
如果联合分支较多,更推荐给所有分支增加一个公共的字面量类型标识字段,类型收窄的可读性和可靠性都会更高:
// 给每个分支加公共的type字段作为可辨识标识 type SomeType = { type: 'user', name: string, age: number, } | { type: 'coordinate', xy: [number, number] } function someFunction(arg: SomeType) { if (arg.type === 'user') { // 自动收窄到用户分支 console.log(arg.name, arg.age) } else { // 自动收窄到坐标分支 console.log(arg.xy) } }
内容的提问来源于stack exchange,提问作者MeineHTMLCodes
相关产品推荐
相关产品推荐

