TypeScript中按日期汇总数组对象价格及reduce类型错误解决
TypeScript 合并同日期价格数组的实现问题
我想把下面的数组:
[{price: 30, date: 05}, {price: 60, date: 05}, {price: 40, date: 06}, {price: 70, date: 06}]
转换成:
[{price: 90, date: 05}, {price: 110, date: 06}]
在 TypeScript 里该怎么实现?我设置初始值时一直碰到这个错误:
Types of parameters 'acc' and 'previousValue' are incompatible.
我尝试的代码如下:
const reducedExpenses = expenses.reduce( (acc, { date, price }, index) => { if (acc[index].date === date) { return { ...acc[index], price: (acc[index].price += price) }; } return acc.push({ date, price, }); }, [{ date: -1, price: 0 }] );
问题分析
你的代码有两个核心问题:
- 返回值类型混乱:
reduce要求回调函数的返回值类型必须和累加器初始值一致,但你有时返回单个对象,有时返回acc.push()的结果(数组长度,数字类型),直接导致类型不兼容报错。 - 逻辑错误:用原数组的循环索引
index去匹配累加器数组的项完全不合理,累加器数组的索引和原数组没有对应关系,无法正确找到同日期的项。
正确实现方案
1. 先定义类型(可选但推荐,让类型更清晰)
interface Expense { date: number; price: number; }
2. 基于数组的 reduce 实现
核心逻辑:遍历数组时,在累加器中查找同日期项,存在则累加价格,不存在则新增项,且始终返回累加器数组。
const expenses: Expense[] = [ {price: 30, date: 05}, {price: 60, date: 05}, {price: 40, date: 06}, {price: 70, date: 06} ]; const reducedExpenses = expenses.reduce<Expense[]>((acc, current) => { const existingItem = acc.find(item => item.date === current.date); if (existingItem) { existingItem.price += current.price; } else { acc.push({...current}); } return acc; }, []); // 初始值设为空数组,通过泛型明确类型
3. 更高效的映射实现(适合大数据量)
用对象做中间映射,避免每次遍历累加器数组,最后再转换回数组:
const reducedExpenses = Object.values( expenses.reduce<Record<number, Expense>>((map, current) => { if (!map[current.date]) { map[current.date] = {...current}; } else { map[current.date].price += current.price; } return map; }, {}) );
内容的提问来源于stack exchange,提问作者Mathew
相关产品推荐
相关产品推荐

