TypeScript类变量与局部变量的‘Object is possibly undefined’报错差异
TypeScript严格模式下的类型窄化差异问题
先看示例代码:
type Foo = { a: number; b: number; } class Bar { #a?: Foo; bar() { const a = this.#a?.a; if (!a) {return;} // 报错:Object is possibly 'undefined'. const b = this.#a.b; } bar2() { const obj = this.#getFoo(); const a = obj?.a; if (!a) {return;} // 无报错: const b = obj.b; console.log(b); } #getFoo() : Foo | undefined { return undefined; } }
核心原因:TypeScript对可变/不可变值的类型窄化逻辑不同
bar2中const obj无报错的原因:
obj是const声明的不可变变量,赋值后无法被修改。当通过obj?.a判断并触发return排除a为假的情况后,TypeScript能确定剩余代码里obj必然是Foo类型(如果obj是undefined,obj?.a会是undefined,早就触发return退出了),因此访问obj.b不会报错。bar中this.#a报错的原因:
类私有成员#a是可变的——哪怕刚判断完this.#a?.a,在执行到this.#a.b之前,#a有可能被其他逻辑(比如异步操作、类的其他方法)修改为undefined。TypeScript无法保证类成员在两次访问之间的状态不变,所以不会对类成员做跨语句的类型窄化。let obj也会报错的原因:
let声明的是可变变量,TypeScript无法确保在判断obj?.a之后,obj没有被重新赋值为undefined。只要变量是可变的,TypeScript就不会信任之前的类型判断能延续到后续访问操作,因此同样会触发报错。
内容的提问来源于stack exchange,提问作者Luke Vo
相关产品推荐
相关产品推荐

