TypeScript传入指定属性时禁止传入其他特定属性的实现方法
实现方案
该需求完全可以在TypeScript中实现,核心是通过联合互斥类型+never类型约束,在编译阶段就拦截不符合规则的传参,不需要额外运行时校验。
实现思路
将组件Props拆成两种互斥的传参模式,最终通过联合类型合并:
- 自定义配置模式:不传入
predefinedLabelType,允许使用所有label相关的自定义配置项 - 预定义类型模式:必须传入
predefinedLabelType,此时所有其余label配置项禁止传入,显式传入就会触发类型错误 - 两种模式都保留必填的
children属性,不受互斥逻辑影响
具体代码实现
首先拆分两类配置的类型约束,禁止出现的属性直接标注为never类型:
// 自定义配置模式:允许传所有label配置,禁止传predefinedLabelType type CustomLabelMode = { labelSize?: LabelSize; labelColor?: LabelColor; labelWeight?: LabelWeight; labelCase?: LabelCase; labelVariant?: LabelVariant; predefinedLabelType?: never; }; // 预定义类型模式:必须传predefinedLabelType,禁止传其余label配置 type PredefinedLabelMode = { predefinedLabelType: PredefinedLabelType; labelSize?: never; labelColor?: never; labelWeight?: never; labelCase?: never; labelVariant?: never; }; // 合并公共属性,得到最终的Props类型 type ILabelProps = (CustomLabelMode | PredefinedLabelMode) & { children: string; };
校验效果
- 非法传参会直接触发TS类型报错:
// ❌ 报错:传了predefinedLabelType的同时不允许传labelSize <Label predefinedLabelType="tip" labelSize="lg" children="提示文本" />
- 两类合法传参都可以正常通过校验:
// ✅ 预定义模式:仅传predefinedLabelType和children <Label predefinedLabelType="tip" children="提示文本" /> // ✅ 自定义模式:传任意label配置项和children <Label labelSize="lg" labelColor="danger" children="错误提示" />
上述写法在TypeScript 3.0及以上版本即可正常运行,兼容性覆盖绝大多数项目场景。
内容的提问来源于stack exchange,提问作者Ilija Ivic
相关产品推荐
相关产品推荐

