修复多键分组对象数组函数中的TypeScript错误
解决多键分组函数的TypeScript类型错误
你遇到的类型错误根源在于:递归调用groupByMulti时,返回值类型会根据剩余分组键的数量动态变化——当没有剩余键时返回T[],否则返回嵌套的字典结构,但byFirst[prop]的初始类型被推断为T[],无法兼容后续的字典类型。
下面提供两种无需// @ts-ignore的解决方案:
方案一:定义递归泛型类型明确返回结构
先定义一个递归类型来描述不同层级的分组结果,让TypeScript能准确推导函数返回值:
// 先明确Dictionary类型(如果项目中已有定义可省略) type Dictionary<T> = { [key: string]: T }; // 递归类型:根据剩余键决定当前层级是数组还是嵌套字典 type GroupedResult<T, Keys extends keyof T> = Keys extends never ? T[] : Dictionary<GroupedResult<T, Exclude<Keys, keyof T>>>; export function groupByMulti<T, K extends Array<keyof T>>( dataset: T[], keys: K ): GroupedResult<T, K[number]> { if (keys.length === 0) { return dataset as GroupedResult<T, K[number]>; } const byFirst = groupBy(dataset, keys[0]) as Dictionary<GroupedResult<T, Exclude<K[number], K[0]>>>; const rest = keys.slice(1) as Exclude<K, K[0]>; for (const prop in byFirst) { byFirst[prop] = groupByMulti(byFirst[prop] as T[], rest); } return byFirst as GroupedResult<T, K[number]>; }
说明
GroupedResult递归类型会根据是否还有剩余分组键,动态生成对应的类型结构:无剩余键时返回T[],否则返回嵌套字典。- 调整泛型参数让TypeScript能根据传入的键数组,精准推导最终的返回类型。
方案二:通过条件判断缩小类型范围
如果不想定义复杂的递归类型,可利用rest.length的条件判断,让TypeScript自动识别不同分支的类型:
type Dictionary<T> = { [key: string]: T }; export function groupByMulti<T>(dataset: T[], keys: Array<keyof T>) { if (keys.length === 0) { return dataset; } const byFirst = groupBy(dataset, keys[0]); const rest = keys.slice(1); for (const prop in byFirst) { const result = groupByMulti(byFirst[prop], rest); // 根据剩余键数量判断类型,消除类型不兼容问题 byFirst[prop] = rest.length === 0 ? result : (result as Dictionary<T[]>); } return byFirst; }
说明
- 当
rest.length === 0时,result的类型是T[],直接赋值给byFirst[prop]; - 当还有剩余键时,
result是嵌套字典结构,通过类型断言明确类型,确保赋值合法。
内容的提问来源于stack exchange,提问作者marielle
相关产品推荐
相关产品推荐

