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

如何定义包含联合类型所有成员的TypeScript对象数组类型?

实现包含联合类型/枚举所有成员的对象数组类型检查

要实现「数组必须包含联合类型/枚举的所有成员作为value字段值,否则类型检查报错」的需求,不能直接用SelectValue<Union>[](这种写法只要求数组元素是联合类型的一员,不强制全覆盖),需要自定义工具类型来做强制检查。

完整实现代码

// 基础选项对象类型:修正原代码中label的字面量类型错误,改为通用string类型
export type SelectValue<T = any> = {
  value: T;
  label: string;
};

// 定义联合类型选项
type Options = "email" | "sms";

// 核心工具类型:强制数组必须包含联合类型的所有成员
type AllUnionMembersArray<T, U extends T = T> = 
  [U] extends [never] 
    ? [] 
    : (
      { [K in U]: SelectValue<K> }[U][] & 
      (T extends U ? never : [SelectValue<Exclude<T, U>>, ...AllUnionMembersArray<Exclude<T, U>>])
    );

// ✅ 正确示例:包含所有联合成员,类型检查通过
const validValues: AllUnionMembersArray<Options> = [
  { value: "email", label: "Email" },
  { value: "sms", label: "短信" },
];

// ❌ 错误示例:缺少"sms"成员,类型检查报错
const invalidValues: AllUnionMembersArray<Options> = [
  { value: "email", label: "Email" },
];

适配枚举类型的写法

如果用枚举替代联合类型,同样可以复用这个工具类型:

// 定义枚举
enum NotificationType {
  Email = "email",
  Sms = "sms",
}

// ✅ 正确示例:包含所有枚举成员
const enumValidValues: AllUnionMembersArray<NotificationType> = [
  { value: NotificationType.Email, label: "Email" },
  { value: NotificationType.Sms, label: "短信" },
];

// ❌ 错误示例:缺少枚举成员,类型检查报错
const enumInvalidValues: AllUnionMembersArray<NotificationType> = [
  { value: NotificationType.Email, label: "Email" },
];

原理说明

工具类型AllUnionMembersArray通过递归拆解联合类型,强制数组必须包含每个成员对应的SelectValue实例:

  1. 利用Exclude<T, U>逐步剔除已包含的成员,递归检查剩余成员是否都被覆盖
  2. 通过交叉类型&同时约束数组元素的类型范围和必须包含的成员数量

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 07:25:27