You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript中遍历对象已知属性键出现索引类型错误如何解决?

错误原因

TypeScript 中Object.keys()返回值的类型固定为Array<string>,而你定义的points对象是明确限定了仅包含a/b/c/d/e几个属性,没有声明可接受任意字符串作为键的索引签名。当你尝试用string类型的变量作为索引访问points属性时,TS 无法确定该变量一定是points的合法属性,为了保证类型安全就会抛出此错误。
虽然你可以明确感知到遍历的键都属于points的合法属性,但 TS 的类型系统默认不会做这个推导——因为 JavaScript 允许给对象额外添加未声明属性是合法操作,TS 无法保证运行时item.points上没有其他额外的字符串键。

解决方案

你可以根据自己的业务场景选择以下任意一种方案解决问题:

  • 方案1:对key做类型断言
    直接告诉 TypeScript 遍历的key一定是points的合法属性,修改遍历行即可:
keys.forEach((key) => {
  // 用as断言key是points的合法属性,??0处理可选属性为undefined的情况
  sum += item.points[key as keyof Siswa['points']] ?? 0
});

keyof Siswa['points']会自动推导得到points所有合法键的联合类型:"a" | "b" | "c" | "d" | "e",类型断言后TS就会认可索引的合法性。

  • 方案2:给points添加索引签名
    如果后续points可能扩展其他数字类型的属性,可以直接在类型定义中添加索引签名:
interface Siswa {
  name: string,
  // 声明points可以接受任意字符串作为键,值类型为数字或undefined
  points: { [key: string]: number | undefined, a: number, b: number, c: number, d?: number, e?: number }
}

声明后TS就允许你用任意字符串类型的变量作为索引访问points的属性,不会再报类型错误。

  • 方案3:直接遍历属性值避开key的类型问题
    你可以直接用Object.values()获取points的所有属性值求和,不需要处理key的类型校验,代码更简洁:
function find_average_points(data: Array<Siswa>): Array<{name: string, average: number}> {
  return data.map(item => {
    // 直接遍历值求和,??0处理可选属性为undefined的情况
    const sum = Object.values(item.points).reduce((prev, curr) => prev + (curr ?? 0), 0);
    const average = sum / Object.keys(item.points).length;
    return { name: item.name, average }
  })
}

内容的提问来源于stack exchange,提问作者riki yudha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 14:45:04