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

如何用TypeScript泛型限制对象键为对象数组深层值?

实现TypeScript对象键的严格限制,不存在键触发报错

我正尝试限制对象的允许键,当前代码如下,希望访问不存在于数组元素column.key中的键时,TypeScript能抛出错误:

type GroupBy = {
  column: {
    key: string
  }
};

type GroupBys = [GroupBy, ...GroupBy[]];

type Result<TGroupBys extends GroupBys> = {
  [Key in TGroupBys[number]['column']['key']]: string;
}

const groupBy: GroupBys = [
  {
    column: {
      key: 'foo',
    },
  },
  {
    column: {
      key: 'bar',
    },
  },
];

function getResult<TGroupBys extends GroupBys>(groupBy:TGroupBys): Result<TGroupBys> {
  const result = {};
  for (const k in groupBy) {
    result[groupBy[k].column.key] = 'Some string';
  }
  return result;
}

const result = getResult(groupBy);

// 此操作应合法:
console.log(result['foo']); // "Some string"
console.log(result['bar']); // "Some string"

// 此操作应触发TypeScript错误,因为'blah'不是有效键:
console.log(result['blah']);

问题根源

当前代码中GroupBy的column.key被定义为宽泛的string类型,导致Result<TGroupBys>被推断为{ [key: string]: string }——任意字符串键都被允许,所以访问'blah'不会触发错误。要实现需求,必须让TypeScript知道具体的合法键字面量值。


修改方案

通过保留column.key的字面量类型,让TypeScript能精确识别合法键:

type GroupBy = {
  column: {
    key: string;
  };
};

// 移除groupBy的GroupBys类型标注,添加as const保留字面量类型
const groupBy = [
  {
    column: {
      key: 'foo',
    },
  },
  {
    column: {
      key: 'bar',
    },
  },
] as const;

// 调整泛型,让返回类型严格映射数组中的key字面量
function getResult<T extends readonly GroupBy[]>(groupBy: T): {
  [Key in T[number]['column']['key']]: string;
} {
  // 对result做类型断言,匹配返回类型
  const result = {} as { [Key in T[number]['column']['key']]: string };
  for (const item of groupBy) {
    result[item.column.key as T[number]['column']['key']] = 'Some string';
  }
  return result;
}

const result = getResult(groupBy);

// 合法操作,无错误
console.log(result['foo']);
console.log(result['bar']);

// 触发TypeScript错误:类型“{ foo: string; bar: string; }”上不存在属性“blah”
console.log(result['blah']);

核心要点

  1. as const的作用:将数组和内部对象转为只读的字面量类型,确保key的具体值('foo'、'bar')被TypeScript保留,而非被宽泛推断为string。
  2. 泛型与映射类型:通过T extends readonly GroupBy[]捕获传入数组的具体结构,再用[Key in T[number]['column']['key']]将所有合法键映射为对象的属性,实现严格的键限制。
  3. 类型断言:函数内部对result做类型断言,解决TypeScript无法自动推断循环赋值后对象类型的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 23:49:59