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

TypeScript如何生成包含枚举所有属性的穷尽唯一数组?

实现包含TypeScript枚举所有值的穷尽唯一数组

要实现一个返回包含枚举每个值恰好一次的对象数组(类型为Array<{ id: EnumValue, label: string }>),可以通过两种方式解决:自动生成(推荐)或手动编写时通过类型约束检查。

方案一:自动生成(简洁且无重复风险)

这种方式利用枚举的内置特性,从枚举值直接映射生成数组,天然保证每个枚举值只出现一次,同时通过类型约束确保所有枚举值都被覆盖。

代码示例

// 定义枚举
enum StepId {
  STEP_ONE = 'step-one-id',
  STEP_TWO = 'step-two-id',
}

// 定义枚举值与标签的映射,必须包含所有枚举值,否则编译报错
const stepLabels: Record<StepId, string> = {
  [StepId.STEP_ONE]: 'Step One',
  [StepId.STEP_TWO]: 'Step Two',
};

// 生成目标数组的函数
function getStepArray(): Array<{ id: StepId; label: string }> {
  // Object.values(StepId)返回枚举的所有值,每个值仅出现一次
  return Object.values(StepId).map(id => ({ id, label: stepLabels[id] }));
}

// 调用结果符合预期
getStepArray();
// 返回:
// [
//   { id: StepId.STEP_ONE, label: 'Step One' },
//   { id: StepId.STEP_TWO, label: 'Step Two' }
// ]

优势

  • 穷尽性保障:Record<StepId, string>类型强制stepLabels必须包含所有StepId的键,遗漏任何枚举值都会触发编译错误。
  • 唯一性保障:Object.values(StepId)会返回枚举的每个值一次,生成的数组自然不会出现重复id。
  • 类型安全:返回类型自动推导为目标类型,无需额外手动标注。

方案二:手动编写数组时的类型约束

如果需要手动编写数组,可以通过自定义类型来检查穷尽性和唯一性,但类型逻辑相对复杂,适合短枚举场景。

代码示例

enum StepId {
  STEP_ONE = 'step-one-id',
  STEP_TWO = 'step-two-id',
}

// 工具类型:获取枚举的所有值的联合类型
type EnumValues<T> = T[keyof T];

// 工具类型:检查数组元素id是否唯一
type IsUnique<T extends readonly { id: any }[]> = 
  T extends [infer First, ...infer Rest] 
    ? First['id'] extends Rest[number]['id'] 
      ? never // 存在重复,返回never触发报错
      : IsUnique<Rest> 
    : true;

// 工具类型:检查数组是否包含所有枚举值且id唯一
type ExhaustiveUniqueArray<T extends string | number> = 
  readonly { id: T; label: string }[] & 
  (EnumValues<typeof T> extends (infer U)['id'] ? (IsUnique<U> extends true ? U : never) : never);

// 手动编写数组,违反穷尽性或唯一性都会报错
const stepConfig: ExhaustiveUniqueArray<StepId> = [
  { id: StepId.STEP_ONE, label: 'Step One' },
  { id: StepId.STEP_TWO, label: 'Step Two' },
  // 取消注释下面这行会触发编译错误(重复id)
  // { id: StepId.STEP_TWO, label: 'Step Two' },
  // 遗漏任何枚举值也会触发编译错误
];

说明

  • IsUnique递归检查数组中每个id是否与后续元素重复,存在重复时返回never,触发类型错误。
  • ExhaustiveUniqueArray同时检查数组是否包含枚举的所有值,以及id是否唯一,不符合条件时都会报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 02:52:52