TypeScript可选链===0无报错但>0报对象可能未定义的原因
TypeScript可选链两种比较写法的类型报错差异说明
复现代码
type Person = { account?: { money: number } } const person: Person = {} // case1 无类型报错 if (person.account?.money === 0) { console.log("I have no money"); } // case2 抛出TS2532错误:Object is possibly 'undefined' if (person.account?.money > 0) { console.log("I have money!!"); }
核心差异原因
两种写法表现不一致,核心是TypeScript对不同运算符的类型校验规则不同,结合可选链的返回值特性就会出现这个现象:
- 首先明确可选链的返回值类型:
person.account?.money的类型不是纯number,而是number | undefined。当person.account不存在时,可选链会直接短路返回undefined,不会继续读取money属性;只有account存在时,才会返回number类型的money值。 - case1用的是全等运算符
===:全等比较不要求两边类型一致,哪怕左边是undefined,undefined === 0也是完全合法的JS表达式,运行时只会返回false,不存在非法操作,所以TS不会拦截。 - case2用的是大于运算符
>:这类大小比较属于数值运算范畴,TS的严格校验规则不允许undefined参与这类运算。从运行时逻辑看,undefined转数字会得到NaN,NaN和任何值做大小比较都返回false,这类比较基本都是业务逻辑里的无效代码,所以TS会直接抛错,提示你这个表达式结果可能是undefined,不能直接拿来比大小。
修复方案
要让case2通过校验,只要在比较前显式排除undefined的情况就行:
if (typeof person.account?.money === 'number' && person.account.money > 0) { console.log("I have money!!"); }
内容的提问来源于stack exchange,提问作者Byeongin Yoon
相关产品推荐
相关产品推荐

