如何在TypeScript中实现Props单选项的条件类型约束
实现Props单选项的条件类型约束问题解决方法
问题背景
现有如下结构的Props:
{ option1, option2, option3, option4, general, otherprops }
需求是确保同一时间仅能使用其中一个option。最初的类型定义如下:
interface MyTypes { option1: boolean option2: boolean option3: boolean general: boolean otherprops: string }
尝试修改为以下类型来实现约束:
interface GeneralTypes{ general: boolean otherprops: string } interface Option1Types{ option1: boolean } interface Option2Types{ option2: boolean } interface Option3Types{ option3: boolean } type MyTypes = GeneralTypes & ( Option1Types | Option2Types | Option3Types )
但出现了以下类型错误:
Property 'option1' does not exist on type '(GeneralTypes & Option1) | (GeneralTypes & Option2)| (GeneralTypes & Option3) ' Property 'option2' does not exist on type '(GeneralTypes & Option1) | (GeneralTypes & Option2)| (GeneralTypes & Option3) ' Property 'option3' does not exist on type '(GeneralTypes & Option1) | (GeneralTypes & Option2)| (GeneralTypes & Option3) '
解决方案
之前的写法错误在于:联合类型的每个分支仅包含自己的option属性,当你尝试访问某个option时,TypeScript无法确定当前实例属于哪个分支,因此会报错。要实现互斥选项的约束,需要让每个分支明确仅保留自身的option属性,其他option属性不存在或为never类型。
可以通过以下方式实现:
// 通用属性部分 interface GeneralTypes { general: boolean; otherprops: string; } // 定义所有可选option的键类型 type OptionKeys = 'option1' | 'option2' | 'option3'; // 生成单个option的类型,同时排除其他option type SingleOption<K extends OptionKeys> = { [key in Exclude<OptionKeys, K>]?: never; } & { [key in K]: boolean; }; // 最终的Props类型:通用属性 + 单个互斥option type MyTypes = GeneralTypes & (SingleOption<'option1'> | SingleOption<'option2'> | SingleOption<'option3'>);
代码解释
OptionKeys:统一管理所有互斥的option键,方便后续维护。SingleOption<K>:- 通过
Exclude<OptionKeys, K>排除当前option以外的所有键,并将它们设为?: never,确保这些属性不能被赋值(即使传入也会触发类型错误)。 - 同时明确当前
K对应的option为必填的boolean类型。
- 通过
MyTypes:将通用属性与单个互斥option的联合类型交叉,确保每个实例必须包含通用属性,且仅能拥有一个有效的option。
验证示例
// 合法:仅包含option1 const valid1: MyTypes = { general: true, otherprops: 'test', option1: true }; // 合法:仅包含option2 const valid2: MyTypes = { general: false, otherprops: 'demo', option2: false }; // 非法:同时包含option1和option2 const invalid1: MyTypes = { general: true, otherprops: 'error', option1: true, option2: true }; // 类型错误:option2不能被赋值 // 非法:未包含任何option const invalid2: MyTypes = { general: true, otherprops: 'error' }; // 类型错误:缺少必填的option属性
内容的提问来源于stack exchange,提问作者MaximoConn
相关产品推荐
相关产品推荐

