TypeScript动态键分组存储对象时push方法不存在报错解决方案
问题根源
你遇到的报错和逻辑异常来自三个核心错误:
- 类型定义和存储结构不匹配:你声明的
serviceTable: Services[]代表「每个元素都是Services类型的数组」,TS会默认通过索引取到的项都是单个Services对象,自然不存在数组才有的push方法。 - 键存在性判断逻辑错误:
Object.keys(this.serviceTable)[result.section]写法完全无效,Object.keys返回的是所有键名组成的数组,取这个数组的result.section索引位,根本不是在判断目标键是否存在。 - 追加逻辑缺参数:else分支的
push()没有传入要存储的result对象,就算类型正确也无法存入新值。
正确实现方案
第一步:修正类型定义
你需要的是「动态键(数字/字符串)映射到Services对象数组」的键值对结构,不要用普通数组类型存这类映射,改用TS内置的Record工具类型定义即可:
// 保留原有Services接口 export interface Services { details: { service: string, description: string } } // 修正serviceTable类型:键支持字符串/数字,值为Services类型的数组 public serviceTable: Record<string | number, Services[]> = {};
不推荐用数组存自定义键值对:数组的字符串键会被存为对象属性,遍历、序列化时很容易出现意料外的问题。
第二步:修正分组存储逻辑
修正键判断逻辑,push操作传入要存储的目标对象:
dialogRef.afterClosed().subscribe(result => { if (!result) return; const groupKey = this.randomNumber; // 自定义分组键 // 检查当前分组是否存在 if (!this.serviceTable[groupKey]) { // 分组不存在则初始化数组,存入第一个元素 this.serviceTable[groupKey] = [result]; } else { // 分组存在则直接追加新对象 this.serviceTable[groupKey].push(result); } console.log(this.serviceTable, 'ServiceTable'); });
第三步:分组遍历写法
和你预期的用法一致,注意修正字段取值路径即可(根据接口定义,service字段嵌套在details属性下):
// 遍历数字键3对应的分组 for (let item of this.serviceTable[3]) { console.log(item.details.service); // 输出该分组下所有service字段值 } // 遍历字符串键myCategory对应的分组 for (let item of this.serviceTable['myCategory']) { console.log(item.details.service); }
可选优化方案
如果你的分组键是动态生成、不需要做JSON序列化,用ES6的Map类型存储分组更稳妥,不会出现原型链键名冲突问题:
// 类型定义 public serviceTable = new Map<string | number, Services[]>(); // 存储逻辑 dialogRef.afterClosed().subscribe(result => { if (!result) return; const groupKey = this.randomNumber; if (!this.serviceTable.has(groupKey)) { this.serviceTable.set(groupKey, [result]); } else { this.serviceTable.get(groupKey)!.push(result); } }); // 遍历逻辑 const targetGroup = this.serviceTable.get(3) || []; for (let item of targetGroup) { console.log(item.details.service); }
内容的提问来源于stack exchange,提问作者xRay
相关产品推荐
相关产品推荐

