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

TypeScript如何提取对象值为字面量联合类型实现类型安全groupBy函数

报错原因与基础修复

你遇到的Type 'T[U]' is not assignable to type 'string | number | symbol'报错,是因为T extends Record<string, unknown>只约束了T的键是字符串,没有约束属性值的类型:unknown包含了对象、函数等不能作为对象键的类型,自然不符合索引签名的要求。
只需要给泛型加一层属性值的约束即可修复基础报错:

// 基础修复版,解决类型报错
export const groupBy = <
  T extends Record<string, unknown>,
  U extends keyof T,
  // 加约束:T[U]必须是可以作为对象键的类型
  V extends PropertyKey = T[U] & PropertyKey
>(
  objArr: T[],
  property: U,
): { [key in V]: T[] } => objArr
  .reduce((memo, x) => {
    const value = x[property] as V;
    if (!memo[value]) {
      memo[value] = [];
    }
    memo[value].push(x);
    return memo;
  }, {} as { [key in V]: T[] });

实现精确字面量键类型

要自动提取输入数组属性的字面量类型作为返回键,需要用到TS 5.0及以上版本支持的const泛型,它可以在函数层面实现类似as const的类型收窄效果,不需要用户手动给输入加断言:

// 精确类型版,自动收窄字面量类型作为返回键
export const groupBy = <
  // const修饰泛型,自动收窄输入的字面量类型
  const T extends readonly Record<string, unknown>[],
  U extends keyof T[number],
  // 约束属性值为合法键类型
  V extends PropertyKey = T[number][U] & PropertyKey
>(
  objArr: T,
  property: U,
): { [key in V]: Array<T[number]> } => objArr
  .reduce((memo, x) => {
    const value = x[property] as V;
    if (!memo[value]) {
      memo[value] = [];
    }
    memo[value].push(x);
    return memo;
  }, {} as { [key in V]: Array<T[number]> });

调用效果验证

用你的示例代码直接调用,不需要加as const就能得到精确返回类型:

const data = [
  { name: 'corn cob', value: 17, group: 'item' },
  { name: 'Dirty toilet', value: 6, group: 'item' },
  { name: 'snake', value: 2, group: 'animal' },
  { name: 'tesla', value: 17, group: 'car' },
  { name: 'gurgel', value: 23, group: 'car' },
];

const result = groupBy(data, 'group');
// result类型自动推导为:
// {
//   item: { name: string; value: number; group: 'item' }[];
//   animal: { name: string; value: number; group: 'animal' }[];
//   car: { name: string; value: number; group: 'car' }[];
// }

如果你的TS版本低于5.0,无法使用const泛型,只需要保留上面的泛型约束写法,用户调用时手动给输入数组加as const断言,也能得到完全一致的精确类型效果。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 13:06:09