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

如何在TypeScript中定义无重复元素的字符串组合数组类型

在TypeScript中定义无重复非空字符串组合数组类型

针对你需要限制数组为指定字符串的无重复非空组合(对应数学中的组合概念)的需求,普通的联合类型数组(如CASE[])无法限制重复元素,下面提供两种可行方案:

方案1:精确生成所有非空无重复组合(适合元素数量较少场景)

通过递归类型生成所有符合要求的元组组合,自动覆盖单元素、多元素的所有可能(包括不同顺序的合法组合):

// 定义基础角色类型(替换为你的业务类型)
type Role = 'Operator' | 'Manufacturer' | 'Distributor';

// 递归生成所有非空无重复子集的元组类型
type NonEmptySubset<T extends string> = 
  T extends infer U ? U[] extends (infer V)[] ? 
  V extends U ? [V] | [V, ...NonEmptySubset<Exclude<U, V>>] : never : never : never;

// 最终的用户角色组合类型
type UserRoles = NonEmptySubset<Role>;

测试示例

// 合法赋值(不会报错)
const singleRole: UserRoles = ['Operator'];
const twoRoles: UserRoles = ['Manufacturer', 'Distributor'];
const allRoles: UserRoles = ['Distributor', 'Operator', 'Manufacturer']; // 顺序不影响合法性

// 非法赋值(TypeScript会报错)
const duplicateRole: UserRoles = ['Operator', 'Operator']; // 重复元素
const emptyRole: UserRoles = []; // 空数组
const invalidRole: UserRoles = ['Unknown']; // 不属于指定类型

方案2:通用型唯一元素数组校验(适合任意元素数量)

通过条件类型直接校验数组元素的唯一性、非空性和类型合法性,无需提前枚举所有组合:

type Role = 'Operator' | 'Manufacturer' | 'Distributor';

// 限制数组为非空、元素唯一且属于指定类型
type UniqueArray<T, U extends T[] = []> = 
  U extends [infer First, ...infer Rest] ? 
  Rest extends T[] ? First extends Rest[number] ? never : U : never : 
  U extends T[] ? U extends [] ? never : U : never;

type UserRoles = UniqueArray<Role>;

测试效果

和方案1一致,非法的重复、空数组、未知类型都会被TypeScript自动拦截。

原代码问题说明

你之前的CASE[]类型仅约束了数组元素属于CASE联合类型,但没有限制重复元素和非空,所以无法拦截["A","A"]这类非法值。上述两种方案通过TypeScript的条件类型和递归特性,补全了这两个约束。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 23:04:53