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

为Array.reduce添加泛型类型实现数组二分分组的问题

TypeScript中数组分区函数的reduce类型报错解决

我原本在Stack Overflow上找到了一个用JavaScript实现的数组分区函数,通过验证函数把数组拆分为两个数组:

function partition(array, isValid) {
  return array.reduce(([pass, fail], elem) => {
    return isValid(elem) ? [[...pass, elem], fail] : [pass, [...fail, elem]];
  }, [[], []]);
}

const [pass, fail] = partition(myArray, (e) => e > 5);

我用TypeScript改写后得到以下代码,它能正常运行:

const separateArray = <T>(array: T[], condition: (e: T) => boolean): [T[], T[]] => {
  return array.reduce(([passed, failed], elem: T) => condition(elem) ? [
    [...passed, elem], failed
  ] : [passed, [...failed, elem]],[[],[]])
}

但当我尝试给reduce的第一个参数(累加器)指定[T[], T[]]类型时,出现了错误:
错误代码片段:

return array.reduce(([passed, failed]: [T[], T[]] ......

错误信息:

Type 'T[][]' is not assignable to type '[T[], T[]]'.
  Target requires 2 element(s) but source may have fewer.

我试过把类型改成[any[],any[]]或[any, any],但错误依然存在,以下是解决方法:


错误原因

TypeScript会把初始值[[],[]]默认推断为T[][](可变长度的数组数组),而不是你需要的[T[], T[]](固定长度为2的元组)。当你给累加器指定元组类型时,初始值的类型和累加器类型不匹配,就会抛出错误。

解决方案1:给初始值显式标注元组类型

直接把初始值断言为元组类型,让TypeScript明确知道这是固定长度的两个数组:

const separateArray = <T>(array: T[], condition: (e: T) => boolean): [T[], T[]] => {
  return array.reduce(([passed, failed]: [T[], T[]], elem: T) => 
    condition(elem) ? [[...passed, elem], failed] : [passed, [...failed, elem]],
    [[], []] as [T[], T[]]
  );
};

解决方案2:通过reduce的泛型参数指定累加器类型

利用Array.reduce的泛型重载,直接指定累加器的类型为[T[], T[]],这样不需要单独给累加器参数标注类型,TypeScript会自动完成推断:

const separateArray = <T>(array: T[], condition: (e: T) => boolean): [T[], T[]] => {
  return array.reduce<[T[], T[]]>(([passed, failed], elem) => 
    condition(elem) ? [[...passed, elem], failed] : [passed, [...failed, elem]],
    [[], []]
  );
};

这两种方法都能解决类型不匹配的问题,让代码既满足类型安全,又能正常运行。


内容的提问来源于stack exchange,提问作者Ignacio Ambía

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 15:31:04