如何正确处理TypeScript中reduce处理联合类型数组的类型问题?
解决TypeScript中数组联合类型的reduce类型不兼容问题
问题背景
现有segregateIds函数,用于根据string-to-boolean映射表,将string[]或number[]类型的ID列表分为两组。实现后出现TypeScript错误:reduce无法兼容string[]或number[]的联合类型输入。要求不能将类型改为Array<string|number>,需解决该TS错误。
原错误代码:
const segregateIds = ( ids: string[] | number[], optionsById: Record<string, boolean>, ): { correctIds: string[] | number[]; incorrectIds: string[] | number[] } => { return ids.reduce<{ correctIds: string[] | number[]; incorrectIds: string[] | number[] }>( (accum: { correctIds: string[] | number[]; incorrectIds: string[] | number[] }, id: string | number) => { if (optionsById[id]) { accum.correctIds.push(id); } else { accum.incorrectIds.push(id); } return accum; }, { correctIds: [], incorrectIds: [], } ); };
解决方案:泛型约束保证类型一致性
修改后的代码:
const segregateIds = <T extends string | number>( ids: T[], optionsById: Record<string, boolean>, ): { correctIds: T[]; incorrectIds: T[] } => { return ids.reduce( (accum, id) => { if (optionsById[String(id)]) { accum.correctIds.push(id); } else { accum.incorrectIds.push(id); } return accum; }, { correctIds: [] as T[], incorrectIds: [] as T[] } ); };
关键修改说明
- 引入泛型
T extends string | number,约束输入的ID类型为纯string或纯number,确保输入数组是string[]或number[],而非混合类型,完全匹配原需求。 - 初始值数组通过
as T[]断言类型,让TypeScript明确两个结果数组的类型与输入数组完全一致,解决reduce初始值的类型推断歧义。 - 访问
optionsById时,用String(id)统一转换ID为字符串,适配Record<string, boolean>的键类型,同时消除number类型作为键时的隐式转换警告。
原错误原因
原代码中,ids是联合类型string[] | number[],reduce的初始值数组被TypeScript推断为never[](无法确定具体类型);同时,id是string | number类型,往correctIds/incorrectIds(string[] | number[])中push时,TypeScript无法保证类型匹配(比如correctIds是string[]但id是number),因此抛出类型错误。
内容的提问来源于stack exchange,提问作者Vedant
相关产品推荐
相关产品推荐

