如何为包含至少各一个指定类型对象的数组定义TypeScript类型?
TypeScript 实现至少包含指定类型元素的数组类型
问题背景
现有三个TypeScript类型:
type mainType = {type:'main', name?:string} type contentType = {type:'content', text?:string} type buttonType = {type:'button', name:string}
需要定义一个数组类型,要求数组至少包含这三种类型的对象各一个,元素顺序任意,还能包含多个同类型元素(示例如下):
[ {type:'main'}, {type:'main', name:'Some name'}, {type:'content', text:"Some text"}, {type:'button', name:'Add'}, {type:'button', name:'Submit'} ]
常规方案的局限:
- 用联合类型
(mainType | contentType | buttonType)[]没法检查是否缺失某类对象; - 用扩展运算符固定顺序的写法(比如
[mainType, contentType, buttonType, ...AllTypes[]])只能适配特定顺序,无法满足任意排列需求。
解决方案
可以通过条件类型+数组元素类型推断实现,核心是先让数组元素是三个类型的联合,再强制数组的元素类型集合必须覆盖所有目标类型。
代码实现
// 先把三个类型合并成联合类型 type AllTypes = mainType | contentType | buttonType; // 辅助类型:递归检查数组里是否包含指定类型U type Includes<T extends any[], U> = T extends [infer First, ...infer Rest] ? First extends U ? true : Includes<Rest, U> : false; // 最终的数组类型:必须同时包含三种类型才有效,否则返回never触发错误 type RequiredArray<T extends AllTypes[]> = Includes<T, mainType> extends true ? Includes<T, contentType> extends true ? Includes<T, buttonType> extends true ? T : never : never : never;
使用示例
// 合法:包含所有三种类型,顺序任意,还有重复的mainType const validArray: RequiredArray<[ {type:'main'}, {type:'button', name:'Add'}, {type:'content', text:"Some text"}, {type:'main', name:'Some name'} ]> = [ {type:'main'}, {type:'button', name:'Add'}, {type:'content', text:"Some text"}, {type:'main', name:'Some name'} ]; // 非法:缺失contentType,TypeScript会报错 const invalidArray: RequiredArray<[ {type:'main'}, {type:'button', name:'Add'} ]> = [ {type:'main'}, {type:'button', name:'Add'} ];
说明
Includes辅助类型会递归遍历数组的每个元素,判断目标类型是否存在;RequiredArray通过嵌套条件判断,确保数组同时包含三种类型,只要缺一种就返回never,触发类型检查错误;- 这种写法完全支持任意元素顺序,也允许添加多个同类型元素。
内容的提问来源于stack exchange,提问作者J Pel
相关产品推荐
相关产品推荐

