如何增强TypeScript联合类型自动补全?传递icon时屏蔽label提示
实现互斥属性的类型约束
你当前的代码中,LablededBadge | IconBadge的联合类型允许同时传入icon和label,因为对象字面量只要满足联合类型中至少一个接口的要求就会被通过。要实现“传其中一个属性时,另一个属性不能存在”的约束,TypeScript是可以做到的,有两种常用方案:
方案一:添加区分字段(区分联合类型)
给两个接口添加一个共同的字面量类型字段,让TypeScript能明确区分不同的类型分支,同时自然实现属性互斥:
interface LablededBadge { type: 'label'; // 区分字段,固定为'label' label: string; } interface IconBadge { type: 'icon'; // 区分字段,固定为'icon' icon: string; } export const Badge = (props: LablededBadge | IconBadge) => { return "Badge"; } // 合法调用 Badge({ type: 'label', label: '标签' }); Badge({ type: 'icon', icon: '图标' }); // 非法调用,TypeScript会报错 Badge({ type: 'icon', icon: '图标', label: '标签' });
这种方案的优点是类型清晰,后续如果需要在函数内部做分支逻辑(比如根据type渲染不同内容)也更方便。
方案二:用工具类型实现无额外字段的互斥
如果不想添加额外的区分字段,可以通过自定义工具类型,强制两个接口的属性互斥:
// 自定义工具类型:实现两个类型的属性互斥 type Exclusive<T, U> = (T & Partial<Record<keyof U, never>>) | (U & Partial<Record<keyof T, never>>); interface LablededBadge { label: string; } interface IconBadge { icon: string; } export const Badge = (props: Exclusive<LablededBadge, IconBadge>) => { return "Badge"; } // 合法调用 Badge({ label: '标签' }); Badge({ icon: '图标' }); // 非法调用,TypeScript会提示类型错误 Badge({ icon: '图标', label: '标签' });
这个Exclusive工具类型的逻辑是:要么是T类型且U的属性只能是never(即不能存在),要么是U类型且T的属性只能是never,从而实现属性互斥的约束。
内容的提问来源于stack exchange,提问作者Hazem Alabiad
相关产品推荐
相关产品推荐

