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

如何在TypeScript中实现groupBy函数动态排除指定键的类型?

TypeScript groupBy函数类型优化:实现按指定键分组后排除该键的类型

问题场景

你编写了一个groupBy函数,期望调用时能根据传入的分组键,自动推导出去除该键后的类型:

原函数代码:

const groupBy = <T extends Record<keyof T, unknown>>(arr: T[], key: keyof T) => {
    return arr.reduce((prev, { [key]: k, ...rest }) => {
        if (!prev[k]) prev[k] = [] as Omit<T, keyof T>[];
        prev[k].push(rest);

        return prev;
    }, {} as Record<keyof T, Omit<T, keyof T>[]>);
};

定义的类型和数组:

type MyType = {
   city: number,
   name: string
}

const L: MyType[] = [
   { city: 1, name: "name1" },
   { city: 1, name: "name2" },
   { city: 2, name: "name3" },
   { city: 2, name: "name4" }
]

期望调用const grouped = groupBy(L, "city")时,grouped的类型为Record<number, Omit<MyType, "city">[]>——即分组键对应的值类型作为Record的键,数组项自动排除该分组键。

解决方案

完全可行,只需调整泛型定义,把分组键作为独立的泛型参数,让TypeScript精准推导类型:

修改后的groupBy函数:

const groupBy = <T extends Record<string, unknown>, K extends keyof T>(arr: T[], key: K) => {
    return arr.reduce((prev, { [key]: k, ...rest }) => {
        if (!prev[k]) {
            prev[k] = [] as Omit<T, K>[];
        }
        prev[k].push(rest);
        return prev;
    }, {} as Record<T[K], Omit<T, K>[]>);
};

关键调整说明

  • 新增泛型参数K extends keyof T:捕获具体的分组键类型(比如调用时的"city"),而非宽泛的keyof T联合类型。
  • 返回值类型改为Record<T[K], Omit<T, K>[]>:
    • T[K]对应分组键值的类型(比如MyType["city"]就是number);
    • Omit<T, K>是从T中排除指定键K后的类型(比如Omit<MyType, "city">即{ name: string })。
  • 修正reduce初始值的类型断言,与返回值类型保持一致。

现在调用groupBy(L, "city")时,grouped的类型会自动推导为Record<number, { name: string }[]>,完全符合你的预期。

内容的提问来源于stack exchange,提问作者Elyasaf755

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 00:15:45