为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
相关产品推荐
相关产品推荐

