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

如何在TypeScript中创建包含联合类型所有成员的严格数组类型?

实现包含联合类型所有成员的严格数组类型

给定联合类型:

type MyUnion = 'foo' | 'bar' | 'baz';

需要创建StrictArrayOfUnion类型,实现以下效果:

  • 数组必须包含联合类型的所有成员,顺序无关;
  • 缺少任意成员、包含重复成员(导致缺少其他成员)、包含非法成员的数组都会触发类型报错。

示例代码:

type MyStrictUnionType = StrictArrayOfUnion<MyUnion>;

// 合法示例
const a: MyStrictUnionType = ['foo', 'bar', 'baz'];
const b: MyStrictUnionType = ['foo', 'baz', 'bar']; // 顺序不影响

// 非法示例(均会报错)
const c: MyStrictUnionType = ['foo', 'bar']; // 缺少'baz'
const d: MyStrictUnionType = ['foo', 'foo', 'baz']; // 缺少'bar'
const e: MyStrictUnionType = ['foo', 'boo', 'baz']; // 缺少'bar'且包含非法成员'boo'

本质是要在TypeScript中实现类似以下JavaScript逻辑的类型校验:

const myUnion = ["foo", "bar", "baz"];
const hasAllUnionMembers = (arr) => myUnion.every(unionMember => arr.includes(unionMember));

解决方案

可以通过类型条件判断和联合类型的分布式特性实现该类型:

type StrictArrayOfUnion<U> = T extends readonly any[]
  ? (U extends T[number] ? true : false) extends true
    ? T
    : never
  : never;

类型解析

  • 首先,T extends readonly any[] 确保我们处理的是数组类型,同时数组元素会自动被约束为U的成员(只有合法数组会被返回);
  • 核心校验逻辑U extends T[number] ? true : false:利用联合类型的分布式特性,把U拆成单个成员逐一检查——每个成员是否存在于数组元素的联合类型T[number]中。所有成员都存在时结果为true,否则为false;
  • 最后,校验通过时返回原数组类型T,否则返回never触发类型报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 00:07:42