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

TypeScript中如何使用reduce()按值合并对象数组?

解决TypeScript中reduce分组对象的问题

你的问题核心是类型不匹配加逻辑方向错误,咱们一步步梳理清楚:

错误原因分析

  1. 类型注解与实际返回值不匹配:你给reduce标注的类型<{ [index: number]: any }>声明最终要返回一个对象,但初始值用了[](数组),且回调函数里返回的也是数组[...res, {...}]。这直接导致TypeScript报错——普通对象没有Symbol.iterator(只有数组、字符串这类可迭代对象才有),所以...res展开对象时触发了2488错误。
  2. 分组逻辑偏差:你想要的是把同buildingId的对象合并到同一个数组中,最终应该得到{ [buildingId: number]: 对应对象数组 }的结构,而非把每个分组对象塞进大数组里。

修正后的代码

// 假设sections的类型为 Array<{ buildingId: number; /* 其他属性 */ }>
const groupedByBuildingId = sections.reduce<Record<number, typeof sections[0][]>>(
  (res, section) => {
    // 获取当前buildingId对应的数组,无则初始化空数组
    const existingSections = res[section.buildingId] || [];
    // 更新对象,将当前section加入对应数组
    res[section.buildingId] = [...existingSections, section];
    // 返回更新后的对象,而非数组
    return res;
  },
  {} // 初始值改为空对象,匹配类型注解要求
);

关键修正点

  • 初始值替换为{}:因为我们要构建的是键值对对象,不是数组。
  • 回调内直接操作对象属性:无需生成新数组,直接对res的buildingId属性做数组拼接。
  • 更精确的类型定义:用Record<number, typeof sections[0][]>替代any,让类型更安全——Record<K, V>表示键为K类型、值为V类型的对象,这里值就是sections元素组成的数组。

补充说明

你之前误解了报错的指向:报错说的是{ [index: number]: any }这个对象类型没有迭代器,和number本身无关。只有数组、字符串、Map、Set这类实现了Symbol.iterator接口的对象,才能用...展开到数组中,普通键值对对象不支持这种操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 14:45:27