Angular动态提取子数组值到主对象时的类型错误问题
解决TypeScript动态属性索引类型错误:提取子数组值到主对象
需求说明
需要将对象中子数组的元素提取为对象的动态属性,示例如下:
初始数组:
myArray = [{'ID' : 1, 'addDetail' : ['test 1', 'test 2']}]
期望得到的数组:
myArray = [{'ID' : 1, 'line1' : 'test 1', 'line2' : 'test 2', 'addDetail' : ['test 1', 'test 2']}]
尝试的代码
this.partiesdatalist = this.partiesdatalist.map(item => { const addDetail = item.addDetail; addDetail?.forEach((detail, index) => { item[`line${index + 1}`] = detail; }); return item; });
遇到的错误
元素隐式具有 "any" 类型,因为类型为
line${number}的表达式不能用于索引类型。
错误出现在这一行:
item[`line${index + 1}`] = detail;
解决方案
这个错误是TypeScript类型检查机制导致的:默认情况下,TypeScript只允许使用对象类型中已声明的键进行索引,而line${index+1}是动态生成的键,不在item的原始类型定义范围内。
方案1:定义支持动态索引的类型(推荐)
为item定义接口,明确支持line开头的数字后缀属性:
interface PartyItem { ID: number; addDetail: string[]; // 允许以line开头后跟数字的键,值为string类型 [key: `line${number}`]: string; }
之后在处理数组时,指定partiesdatalist的类型为PartyItem[],或在map中断言item的类型:
this.partiesdatalist = (this.partiesdatalist as PartyItem[]).map(item => { const addDetail = item.addDetail; addDetail?.forEach((detail, index) => { item[`line${index + 1}`] = detail; }); return item; });
方案2:临时类型断言(快速解决,适合简单场景)
如果不想定义完整接口,可在赋值时将item断言为Record<string, any>,跳过类型检查:
this.partiesdatalist = this.partiesdatalist.map(item => { const addDetail = item.addDetail; addDetail?.forEach((detail, index) => { // 断言item为任意键值对类型 (item as Record<string, any>)[`line${index + 1}`] = detail; }); return item; });
内容的提问来源于stack exchange,提问作者grabrep gg
相关产品推荐
相关产品推荐

