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

TypeScript中Redux切片对象数组reduce求和异常(返回拼接)求助

Redux对象数组求和异常:得到字符串拼接而非数值总和

我在Redux切片中存储了一个Expense对象数组,想要计算所有对象中amount字段的数值总和,但使用reduce函数后得到的却是字符串拼接结果,不是预期的数值相加。

相关类型与Redux初始状态代码

export type Expense = {
    id: string;
    title: string;
    amount: number;
    date: string;
};

type ExpensesState = {
    expenses: Expense[];
};

const initialState: ExpensesState = {
    expenses: [],
};

我的reduce求和代码

const total = expenses.reduce(
    (accumulator, expense) => accumulator + expense.amount,
    0
);

对比测试(能正常求和)

我写了个测试示例,相同的reduce逻辑可以正确计算总和:

const items = [{foo: 'bar', amount: 1}, {foo: 'bar', amount: 12}]
const total = items.reduce((acc, i) => acc + i.amount, 0)
console.log(total) // 输出13,符合预期

该示例的类型定义为:

type items = {
    foo: string,
    amount: number
}[]

无效尝试

我误以为是类型定义的问题,把Expense改成了数组类型,但问题依旧:

export type Expense = {
    id: string;
    title: string;
    amount: number;
    date: string;
}[];

问题根源与解决方案

问题本质

TypeScript的类型定义只是编译时约束,你Redux中存储的expense.amount实际是字符串类型——虽然你定义成了number,但运行时数据是字符串,导致+运算符执行了字符串拼接,而非数值相加。

解决步骤

  1. 恢复正确的类型定义:把Expense改回单个对象类型(不要定义成数组),原来的ExpensesState里expenses: Expense[]的写法是正确的。
  2. 确保amount是数值类型:
    • 存入Redux前转换:如果数据来自API或表单输入,在dispatch添加/更新expense的action前,把amount转为数字,比如用Number(amountStr)或parseFloat(amountStr)。
    • 求和时强制转换:如果暂时无法修改存入的数据,在reduce里直接转换:
      const total = expenses.reduce(
          (accumulator, expense) => accumulator + Number(expense.amount),
          0
      );
      
  3. 检查Redux action逻辑:确认添加expense的action中,传递的amount是数值而非字符串,比如处理表单提交时,不要直接把输入框的字符串值存进去。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 06:37:21