TypeScript访问类可选动态键对象属性的正确语法是什么?
问题原因与正确解决方案
首先明确三个核心问题:
- 你最初的
Object is possibly 'undefined'报错,根源是bobMap本身是可选属性,可能为undefined,直接对undefined做动态键访问/赋值必然触发类型报错。 - 你之前的可选链写法位置错误:
this?.bobMap[xxx]只对this做了可选判断(类实例方法中this不可能为undefined,这里判断毫无意义),bobMap后没有加可选链,访问动态键时bobMap仍可能为undefined,因此报错没有消失。 - 你写的
!this?.bobMap || {}[_${bobStatus}]存在两个错误:一是运算符优先级问题,表达式实际等价于(!this?.bobMap) || ({}[xxx]),逻辑完全不符合预期;二是空对象{}默认没有字符串索引签名,因此触发索引类型报错。
正确的可选链访问语法
TypeScript 中访问可选对象的动态键,可选链需要加在可选对象本身的后面,语法为:可选对象?.[动态键]
对应你的场景,单纯读取值的正确写法是:this.bobMap?.[${bobStatus}]
该写法会在bobMap不为null/undefined时访问对应键值,否则直接返回undefined,不会触发类型报错。
你的场景的完整可运行代码
由于你需要对动态键做赋值操作,可选链表达式不能作为赋值左值,因此必须先排除bobMap为undefined的情况,推荐用空值合并赋值运算符初始化:
getBobLayer(bobStatus: BobStatusType) { // 仅当bobMap为undefined/null时,初始化为符合类型定义的空对象 this.bobMap ??= {} as {[key: string]: BobSource}; const statusKey = `${bobStatus}`; if (!this.bobMap[statusKey]) { this.bobMap[statusKey] = new BobSource({ features: [] }); } return this.bobMap[statusKey]; }
如果不想用类型断言,也可以用显式判断分支处理,TypeScript会自动收窄bobMap的类型:
getBobLayer(bobStatus: BobStatusType) { const statusKey = `${bobStatus}`; if (!this.bobMap) { this.bobMap = { [statusKey]: new BobSource({ features: [] }) }; return this.bobMap[statusKey]; } if (!this.bobMap[statusKey]) { this.bobMap[statusKey] = new BobSource({ features: [] }); } return this.bobMap[statusKey]; }
内容的提问来源于stack exchange,提问作者Caleb Jay
相关产品推荐
相关产品推荐

