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

修复多键分组对象数组函数中的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 12:15:38