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

如何让TypeScript检查数组是否包含所有字符串字面量类型成员?

实现包含所有联合类型成员的数组类型校验

你可以通过条件类型+数组类型约束实现需求,核心是让数组的元素类型覆盖原联合类型的所有成员,利用TypeScript的类型检查机制,在数组缺少成员时触发报错。

具体实现代码

type Dessert = 'cake' | 'chocolate' | 'cookie';

// 辅助类型:校验数组是否包含联合类型的全部成员
type IncludesAll<T extends string, U extends T[]> = 
  Exclude<T, U[number]> extends never ? U : never;

// 符合要求的数组:正常通过校验
const arrWithAllDessertTypes: IncludesAll<Dessert, ['cake', 'chocolate', 'cookie']> = 
  ['cake', 'chocolate', 'cookie'];

// 错误示例:缺少'cookie',TypeScript会抛出类型不匹配错误
const badArr: IncludesAll<Dessert, ['cake', 'chocolate']> = 
  ['cake', 'chocolate']; // 报错提示:类型"['cake', 'chocolate']"无法赋值给类型"never"

原理说明

  • Exclude<T, U[number]>会计算出联合类型T中,不在数组元素类型U[number]里的成员。
  • 若数组包含T的所有成员,Exclude的结果为never,此时IncludesAll返回数组本身的类型,赋值正常。
  • 若数组缺少成员,Exclude会返回缺失的成员类型,此时IncludesAll返回never,数组无法赋值给never类型,触发报错。

更简洁的写法(结合const断言)

如果不想手动重复编写数组类型,可以用const断言让TypeScript推导数组的字面量类型,同时通过函数约束确保它覆盖原联合类型:

type Dessert = 'cake' | 'chocolate' | 'cookie';

type AssertAllMembers<T extends string> = <U extends T[]>(
  arr: U extends readonly T[] ? Exclude<T, U[number]> extends never ? U : never : never
) => U;

const assertAllDesserts = AssertAllMembers<Dessert>();

// 正常通过校验
const goodArr = assertAllDesserts(['cake', 'chocolate', 'cookie'] as const);

// 错误示例:缺少'cookie',触发报错
const badArr = assertAllDesserts(['cake', 'chocolate'] as const);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 13:15:57