TypeScript动态赋值对象属性时报ts(7053)、ts(2532)错误怎么解决?
错误根因
- 报错
ts(7053):Items接口的keyName为宽泛的string类型,但ReturnData仅允许foo、bar、baz三个属性作为合法键,TypeScript无法确认keyName一定属于ReturnData的合法键范围,因此不允许用字符串直接索引ReturnData类型对象。 - 报错
ts(2532):代码未校验items[index]是否存在,TypeScript担心索引越界导致取到undefined值。
优化方案
方案1(推荐,从类型定义层面保证安全)
调整Items接口的keyName类型,直接限制为ReturnData的合法键联合类型,从源头避免非法键传入:
// 调整后的Items接口 interface Items { step: number; keyName: keyof ReturnData; // 限制keyName只能是ReturnData的属性名 value: string; }
同时在定时器回调中先校验当前索引对应的元素是否存在,避免越界问题,修改后的函数逻辑:
const myFunc = (items: Items[]): Promise<ReturnData> => { let index = 0; let returnData: ReturnData = { foo: '', bar: '', baz: '' }; return new Promise(resolve => { const interval = setInterval(() => { const currentItem = items[index]; // 元素不存在直接终止逻辑,避免undefined报错 if (!currentItem) { clearInterval(interval); resolve(returnData); return; } // 此时currentItem一定存在,keyName也一定是ReturnData的合法键 returnData[currentItem.keyName] = currentItem.value; if (currentItem.step === items.length) { clearInterval(interval); resolve(returnData); } else { index += 1; } }, 250); }) }
方案2(无需修改原Items接口,适配已有逻辑)
如果不能修改原始的Items接口定义,可以在赋值时对keyName做类型断言,告知TypeScript该值一定属于ReturnData的合法键:
// 仅修改赋值语句即可,其余逻辑不变 returnData[items[index].keyName as keyof ReturnData] = items[index].value;
该方案需要自行保证所有传入的Items数组的keyName都是ReturnData的合法属性,否则运行时可能出现不符合预期的行为。
两种方案均无需使用any类型,完全符合TypeScript的类型安全规范。
内容的提问来源于stack exchange,提问作者decho
相关产品推荐
相关产品推荐

