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

如何用TypeScript为枚举值属性设置唯一ID类型校验?

TypeScript 实现 EnumValue 下对象 ID 唯一性校验

需求说明

现有如下TypeScript数据结构,需添加类型校验规则:

  • 每个EnumValue枚举值对应的子对象中,所有Product类型的属性必须拥有唯一的id
  • 保留as const satisfies语法,确保代码中能正确使用数据的模型类型

原始代码:

interface Product {
    id: number
    name: string;
}

enum EnumValue {
  'VALUE1' = 'VALUE1',
  'VALUE2' = 'VALUE2',
  'VALUE3' = 'VALUE3',
}

const data = {
  'VALUE1': {
    num1: {id: 1, name: '2'},
    num2: {id: 2, name: '2'},
  },
    'VALUE2': {
    num1: {id: 1, name: '2'},
  },
    'VALUE3': {
    num1: {id: 1, name: '2'},
  },
} as const satisfies { readonly [key in EnumValue]: { [key: string]: Product} };

已知一段针对数组对象唯一id的校验代码,但不清楚如何适配到对象结构的遍历校验。

解决方案

1. 定义辅助类型

  • ObjectValues<T>:提取对象的所有属性值为数组类型
  • HasUniqueIds<T>:校验对象中所有Product的id是否唯一,重复则返回never触发类型错误
// 提取对象的所有属性值为数组
type ObjectValues<T> = T extends object ? T[keyof T][] : never;

// 校验对象中所有Product的id是否唯一,重复则返回never
type HasUniqueIds<T extends { [key: string]: Product }> = 
  ObjectValues<T> extends infer Arr extends Product[]
    ? Arr[number]['id'] extends infer Id
      ? Id extends number
        ? // 判断当前id是否在数组中出现多次,是则返回never
          Extract<Arr, { id: Id }> extends [infer _, infer __, ...any[]]
          ? never
          : T
        : T
      : T
    : T;

2. 定义合法数据类型

基于上述辅助类型,定义ValidData类型,要求每个EnumValue对应的子对象必须通过HasUniqueIds校验:

type ValidData = {
  readonly [K in EnumValue]: HasUniqueIds<{ readonly [key: string]: Product }>;
};

3. 应用校验到数据

将原数据的satisfies类型替换为ValidData,即可实现自动校验:

// 合法示例:无重复id,无类型错误
const validData = {
  VALUE1: {
    num1: { id: 1, name: '2' },
    num2: { id: 2, name: '2' },
  },
  VALUE2: {
    num1: { id: 1, name: '2' },
  },
  VALUE3: {
    num1: { id: 1, name: '2' },
  },
} as const satisfies ValidData;

// 非法示例:VALUE1下存在重复id,TypeScript会抛出类型错误
const invalidData = {
  VALUE1: {
    num1: { id: 1, name: '2' },
    num2: { id: 1, name: '2' }, // 此处id重复,触发错误
  },
  VALUE2: {
    num1: { id: 1, name: '2' },
  },
  VALUE3: {
    num1: { id: 1, name: '2' },
  },
} as const satisfies ValidData;

原理说明

  • ObjectValues<T>将每个EnumValue对应的子对象转换为Product数组,方便复用数组的id唯一性校验逻辑
  • HasUniqueIds<T>通过Extract<Arr, { id: Id }>提取所有包含当前id的元素,若提取结果长度≥2,则判定为重复id,返回never使satisfies触发类型错误
  • ValidData通过映射类型遍历所有EnumValue,确保每个子对象都通过唯一性校验

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 05:12:12