You need to enable JavaScript to run this app. 为什么该示例中的TypeScript类型守卫没有正常生效?
优惠活动
大模型
产品
解决方案
定价
更多

为什么该示例中的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 12:36:01