如何解决TS7053错误且规避性能损耗?TypeScript索引问题
解决TypeScript中数组/对象遍历的类型错误且避免性能损耗
方案1:类型断言(最简单,性能无损耗)
直接将data断言为支持字符串索引的对象类型即可——JavaScript中数组本质也是对象,字符串形式的数字索引(比如"0")访问数组元素完全合法,只是TypeScript的类型系统默认限制了数组只能用数字索引。修改后代码:
function test(data: { [key: string]: any } | any[]) { const x = Object.keys(data).reduce((res: { [key: string]: any }, name: string) => { // 类型断言消除TS错误,运行时逻辑和原代码完全一致 const item = (data as { [key: string]: any })[name]; const key = item?.name || name; // ...你的其他处理逻辑 return res; }, {}); }
该方案没有引入任何额外运行时代码,完全保留原有性能,同时通过类型断言让TypeScript检查通过。
方案2:提前分支处理(类型更安全,性能更优)
如果不想使用类型断言,可以提前判断data的类型,将数组和对象的逻辑分开处理,避免循环内部的重复类型检查:
function test(data: { [key: string]: any } | any[]) { const result: { [key: string]: any } = {}; if (Array.isArray(data)) { // 数组直接使用自身的reduce,索引为数字类型,转字符串作为默认key data.reduce((res, item, index) => { const key = item?.name || String(index); // ...你的处理逻辑(示例:将item存入结果) res[key] = item; return res; }, result); } else { // 对象直接使用原逻辑,无类型问题 Object.keys(data).reduce((res, name) => { const item = data[name]; const key = item?.name || name; // ...你的处理逻辑(示例:将item存入结果) res[key] = item; return res; }, result); } return result; }
这个方案仅做一次类型判断,循环内部无额外分支,性能比循环内判断更优,同时TypeScript能完美推导类型无需断言。若处理逻辑重复,可提取成一个3行以内的小函数,不会造成冗余。
方案3:全局扩展数组类型(进阶场景)
如果你的项目全局需要数组支持字符串索引访问,可以通过声明合并扩展数组类型:
declare global { interface Array<T> { [key: string]: T | undefined; } } function test(data: { [key: string]: any } | any[]) { const x = Object.keys(data).reduce((res: { [key: string]: any }, name: string) => { const item = data[name]; // TS不再报错 const key = item?.name || name; // ...你的处理逻辑 return res; }, {}); }
该方案适合全局需要这种兼容的场景,但会改变数组的默认类型定义,需谨慎使用。
优先推荐方案1或方案2,既能满足性能要求,又能通过TypeScript类型检查。
内容的提问来源于stack exchange,提问作者velis
相关产品推荐
相关产品推荐

