如何正确在Array.prototype.reduce中使用TypeScript解决类型报错?
报错根本原因
所有报错的核心是 TypeScript 无法自动推断 reduce 初始值 [] 的类型,默认会把空数组推断为 never[] 类型,对 never 类型的所有属性/方法调用都会触发类型错误。你之前尝试的 ITask[] | [] 类型标注是冗余的,ITask[] 本身就包含了空数组的场景,额外的联合类型反而会干扰类型推导。
正确实现(两种写法均可)
写法1:给reduce显式传入泛型参数(最推荐)
直接通过泛型指定累加器的类型为 ITask[],TS 会自动推导回调中所有参数的类型,不需要额外标注:
interface ITask { id: string; was: string; } // 给tasks本身标注类型,避免TS自动推断为普通对象数组 const tasks: ITask[] = [ {id: "a", was: "Foo"}, {id: "b", was: "Foo"}, {id: "c", was: "Bad"} ]; const uniqueList = tasks.reduce<ITask[]>((acc, current) => { const x = acc.find(item => item.was === current.was); return !x ? acc.concat(current) : acc; }, []);
写法2:给初始值加类型断言
如果不想写泛型,也可以直接给初始的空数组断言为 ITask[] 类型:
const uniqueList = tasks.reduce((acc, current) => { const x = acc.find(item => item.was === current.was); return !x ? acc.concat(current) : acc; }, [] as ITask[]);
之前写法的问题点
- 写的
reduce<>是空泛型,没有实际指定类型,没有任何作用 - 初始值标注
ITask[] | []属于多余标注,既没有解决类型推断问题,还可能带来额外的类型校验冲突 - 没有给
tasks标注ITask[]类型时,TS 会把它推断为{id: string, was: string}[]字面量类型,和你定义的ITask接口无法自动关联
内容的提问来源于stack exchange,提问作者John Doener
相关产品推荐
相关产品推荐

