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

TypeScript中联合类型数组reduce累加器类型错误及修复方案

解决TypeScript联合数组类型下reduce累加器类型推断错误

问题场景

我编写了一个接收数组参数的TypeScript函数,为了同时支持普通数组Item[]和只读数组readonly Item[],将参数类型定义为Item[] | readonly Item[]。但调用reduce方法做对象累加、传入初始值{}时,TypeScript错误地将累加器acc的类型推断为Item,而非预期的对象类型。只有单独将参数类型设为Item[]或readonly Item[]时,类型错误才会消失,但我需要函数同时兼容两种数组类型。

错误代码示例:

type Item = 'foo' | 'bar';

const func = (arr: Item[] | readonly Item[]) => 
  arr.reduce((acc, item) => ({ ...acc, [item]: item }), {});
  //          ^? 此处acc被错误推断为Item类型

解决方案

无需使用联合类型定义参数,直接将参数类型设置为readonly Item[]即可。因为普通数组Item[]是readonly Item[]的子类型,完全可以赋值给只读数组类型的参数,这样既兼容两种数组类型,又能让TypeScript正确推断累加器的类型。

修正后的代码:

type Item = 'foo' | 'bar';

const func = (arr: readonly Item[]) => 
  arr.reduce((acc, item) => ({ ...acc, [item]: item }), {});
  //          ^? 此处acc被正确推断为{}类型

原理说明

当使用Item[] | readonly Item[]联合类型时,TypeScript会取两种数组类型上reduce方法的交集签名,导致类型推断逻辑出现偏差。而readonly Item[]的reduce方法签名更通用,能与初始值{}配合,正确推断出累加器的对象类型,同时普通数组作为其子类型可以正常传入函数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 18:35:30