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

TypeScript联合类型下typeof判断a为string时b仍报类型错误原因

核心原因

出现这个问题的本质是TypeScript的类型收窄不会追踪解构出来的独立变量之间的关联绑定:

  • 你在参数位置直接把联合类型Type的入参解构为a、b两个独立常量后,两个变量的类型推导是互相独立的,初始类型都为string | number。
  • 当你写typeof a === 'string'做判断时,TS确实会把当前代码块内的a类型收窄为string,但它不会同步关联收窄同作用域下的b——因为解构后b已经是和a无关的独立变量,TS默认不会消耗额外性能追踪这类跨变量的类型绑定关系,所以此时b的类型仍然是string | number,直接返回给标注为string类型的返回值自然会报类型不匹配错误。

你传入{a: 1, b: 'w/e'}时的报错是完全符合预期的:Type本身是两个对象类型的联合,只接受「a、b全为string」或「a、b全为number」两种结构,混合a、b类型的对象本来就不符合类型定义,这个报错也能证明TS并没有把Type错误解析为{a: string | number; b: string | number;}的平铺结构——如果是那样的话,混合类型的入参是不会触发报错的。

修复方案

最稳妥无副作用的修复方式是不要直接解构参数,保留对原入参对象的引用,通过属性访问的方式做判断,TS可以正确对联合类型的对象做判别式收窄:

type Type = {
    a: string;
    b: string;
} | {
    a: number;
    b: number;
};

const func = (obj: Type): string => {
    if (typeof obj.a === 'string') {
        // 此处TS会正确收窄obj为{a:string; b:string}分支,obj.b类型为string,无报错
        return obj.b;
    }
    return 'w/e';
}

// 混合类型入参仍然会正确报错,符合类型约束
// func({a: 1, b: 'w/e'});

如果你坚持要使用解构语法,也可以在收窄a的类型后,对b做手动类型断言,但这种方式安全性稍差,需要自行保证逻辑上b的类型和a是匹配的:

const func = ({a, b}: Type): string => {
    if (typeof a === 'string') {
        return b as string;
    }
    return 'w/e';
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 12:48:09