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

TypeScript如何实现带唯一值约束的枚举数组类型声明

解决方案

你原来的写法存在两个问题:一是Set<Roles>是Set实例的类型,无法直接匹配数组字面量;二是原生TS没有直接校验数组元素唯一性的内置类型,需要自己实现工具类型配合泛型推导实现。


第一步:实现唯一性校验工具类型

// 判断类型T是否在数组U中存在
type Includes<T, U extends any[]> = U extends [infer First, ...infer Rest]
  ? T extends First
    ? true
    : Includes<T, Rest>
  : false;

// 校验数组元素是否唯一
type IsUnique<T extends any[]> = T extends [infer First, ...infer Rest]
  ? Includes<First, Rest> extends true
    ? false
    : IsUnique<Rest>
  : true;

第二步:定义业务枚举和泛型接口

export enum Roles {
  Role1 = 'Role1',
  Role2 = 'Role2',
  Role3 = 'Role3',
}

// 泛型接口,接收permissions对应的数组类型做校验
export interface SomeInterface<T extends Roles[]> {
  // 元素唯一则返回原数组类型,否则返回never触发类型报错
  permissions: IsUnique<T> extends true ? T : never;
}

第三步:使用工厂函数实现自动校验(推荐)

手动声明泛型参数成本较高,用工厂函数可以自动推导数组类型,重复时直接抛出警告:

// 工厂函数定义
function createSomeConfig<T extends Roles[]>(config: SomeInterface<T>) {
  // 若需要运行时校验,可增加如下逻辑
  // if (new Set(config.permissions).size !== config.permissions.length) {
  //   throw new Error('permissions存在重复角色')
  // }
  return config;
}

// 正确示例:无重复,无报错
const validConfig = createSomeConfig({
  permissions: [Roles.Role1, Roles.Role2]
});

// 错误示例:有重复,TS直接抛出类型错误
const invalidConfig = createSomeConfig({
  permissions: [Roles.Role1, Roles.Role1] // 此处会飘红提示类型不匹配
});

内容的提问来源于stack exchange,提问作者Святослав Марюха

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 04:09:00