如何在TypeScript中创建条件类型:含x的数组必须同时包含y和z
TypeScript条件类型实现:包含
x则必须同时包含y和z 需要在TypeScript中创建约束数组的条件类型:当数组包含x元素时,必须同时包含y和z;不包含x时,元素可以自由组合(只要属于指定的可选范围)。示例场景如下:
const allGroups = ['w', 'x', 'y', 'z'] const group1 = ['w'] // 合法 const group2 = ['x'] // 不合法 const group3 = ['x', 'y'] // 不合法 const group4 = ['x', 'y', 'z'] // 合法
方案一:直接枚举合法组合类型
通过拆分两种场景(不含x、含x且必带y/z)定义合法类型:
// 定义可选元素的固定联合类型 const allGroups = ['w', 'x', 'y', 'z'] as const; type GroupItem = typeof allGroups[number]; // 合法组类型:要么不含x,要么同时包含x、y、z(可附加其他元素) type ValidGroup = Exclude<GroupItem, 'x'>[] | (['x', 'y', 'z'] | [...['x', 'y', 'z'], ...Exclude<GroupItem, 'x' | 'y' | 'z'>[]]); // 测试用例 const group1: ValidGroup = ['w']; // ✅ 合法 const group2: ValidGroup = ['x']; // ❌ 不合法(缺少y和z) const group3: ValidGroup = ['x', 'y']; // ❌ 不合法(缺少z) const group4: ValidGroup = ['x', 'y', 'z']; // ✅ 合法 const group5: ValidGroup = ['x', 'y', 'z', 'w']; // ✅ 合法(附加w元素)
说明
as const将数组转为只读元组,确保GroupItem是固定的联合类型'w' | 'x' | 'y' | 'z'Exclude<GroupItem, 'x'>[]表示所有不包含x的合法元素组合['x', 'y', 'z'] | [...['x', 'y', 'z'], ...Exclude<GroupItem, 'x' | 'y' | 'z'>[]]确保含x时必须同时有y和z,还可以附加其他非x/y/z的元素(这里是w)
方案二:用条件类型做动态检查
通过辅助类型判断数组是否满足约束,扩展性更强:
const allGroups = ['w', 'x', 'y', 'z'] as const; type GroupItem = typeof allGroups[number]; // 辅助类型:检查数组是否包含x type HasX<T extends GroupItem[]> = 'x' extends T[number] ? true : false; // 辅助类型:检查数组是否同时包含y和z type HasYAndZ<T extends GroupItem[]> = ('y' extends T[number] && 'z' extends T[number]) ? true : false; // 合法组类型:含x则必须同时含y和z,否则自由组合 type ValidGroup<T extends GroupItem[] = GroupItem[]> = HasX<T> extends true ? HasYAndZ<T> extends true ? T : never : T; // 测试用例 const group1: ValidGroup = ['w']; // ✅ 合法 const group2: ValidGroup = ['x']; // ❌ 不合法 const group3: ValidGroup = ['x', 'y']; // ❌ 不合法 const group4: ValidGroup = ['x', 'y', 'z']; // ✅ 合法 const group5: ValidGroup = ['y', 'z']; // ✅ 合法(不含x)
说明
HasX和HasYAndZ通过extends判断元素是否存在于数组的联合类型中ValidGroup是嵌套条件类型:如果数组含x,则必须同时满足含y和z,否则返回never触发类型报错;不含x时直接允许该数组类型
内容的提问来源于stack exchange,提问作者neeko
相关产品推荐
相关产品推荐

