使用reduce方法遍历对象时如何避免TypeScript类型报错?
问题与解决:用reduce合并对象数组并修复TS及运行时错误
问题描述
需要将数组[{ year: "yyyy" }, { month: "mm" }, { day: "dd" }]合并为单个对象{ year: "yyyy", month: "mm", day: "dd" },使用reduce方法时遇到两类问题:
- TypeScript类型错误:
- 对
curr提示:Type '{ [x: string]: any; }' is not an array type or a string type. - 对
acc[key]提示:Element implicitly has an 'any' type because expression of type 'any' can't be used to index type '{}'
- 对
- 运行时错误:控制台输出
TypeError: Invalid attempt to iterate non-iterable instance. In order to be iterable, non-array objects must have a Symbol.iterator method.
错误原因
- 运行时错误:直接用
for...of遍历普通对象,普通对象默认没有Symbol.iterator迭代器,无法被for...of直接遍历。 - TS类型错误:
- 累加器初始值
{}的类型被推断为{},TS不允许用任意字符串索引该类型。 curr的类型定义过于宽泛,且未正确处理迭代后的键值对类型。
- 累加器初始值
解决代码及关键修改
import "./styles.css"; import { useEffect } from "react"; export default function App() { interface IData { day: string; month: string; year: string; } // 给数据数组指定精确类型:每个元素是IData的部分属性 let data: Partial<IData>[] = [{ year: "yyyy" }, { month: "mm" }, { day: "dd" }]; const updateData = (): IData => { const updatedData = data.reduce((accu, curr) => { // 用Object.entries将对象转为键值对数组,支持for...of遍历 for (const [key, val] of Object.entries(curr)) { // 断言key是IData的属性键,消除TS索引类型错误 accu[key as keyof IData] = val; } return accu; }, {} as IData); // 给累加器指定IData类型,明确最终返回结构 console.log(updatedData); return updatedData; }; // 调用方法测试 useEffect(() => { updateData(); }, []); return <div className="App"></div>; }
关键修改说明
- 修复迭代问题:用
Object.entries(curr)将对象转换为[key, value]格式的数组,让for...of可以正常遍历。 - 类型精确化:
- 给
data数组指定Partial<IData>[]类型,明确每个元素是目标对象的部分属性。 - 给累加器初始值
{} as IData,告诉TS最终会生成一个完整的IData对象,解决索引类型报错。 - 用
key as keyof IData断言键的类型,确保仅使用IData中定义的属性,避免类型不匹配。
- 给
内容的提问来源于stack exchange,提问作者Judoboy Alex
相关产品推荐
相关产品推荐

