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

如何为包含至少各一个指定类型对象的数组定义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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 14:05:19