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,但运行时数据是字符串,导致+运算符执行了字符串拼接,而非数值相加。
解决步骤
- 恢复正确的类型定义:把
Expense改回单个对象类型(不要定义成数组),原来的ExpensesState里expenses: Expense[]的写法是正确的。 - 确保
amount是数值类型:- 存入Redux前转换:如果数据来自API或表单输入,在dispatch添加/更新expense的action前,把
amount转为数字,比如用Number(amountStr)或parseFloat(amountStr)。 - 求和时强制转换:如果暂时无法修改存入的数据,在
reduce里直接转换:const total = expenses.reduce( (accumulator, expense) => accumulator + Number(expense.amount), 0 );
- 存入Redux前转换:如果数据来自API或表单输入,在dispatch添加/更新expense的action前,把
- 检查Redux action逻辑:确认添加expense的action中,传递的
amount是数值而非字符串,比如处理表单提交时,不要直接把输入框的字符串值存进去。
内容的提问来源于stack exchange,提问作者Rik89
相关产品推荐
相关产品推荐

