TypeScript判别联合数组对无效键未报错问题求助
如何让TypeScript联合类型严格互斥,禁止混合属性
你的问题出在TOption和TOptionGroup这两个类型没有互斥约束。TypeScript的联合类型允许对象同时满足多个联合成员的结构(只要属性之间没有冲突),所以一个同时包含displayName/value(属于TOption)和options(属于TOptionGroup)的对象,会被TS判定为同时属于两个类型的交集,自然不会触发错误。
解决方案
要实现严格的类型约束,需要让两个类型互斥——也就是在每个类型中显式声明对方的核心属性为never,这样一旦对象同时包含这些属性,就会触发类型错误。
修改后的类型定义如下:
type Common = { label?: string; disabled?: boolean; }; type TOption = Common & { value: string; displayName: string; selected?: boolean; // 禁止TOption拥有options属性 options?: never; }; type TOptionGroup = Common & { options: TOption[]; // 禁止TOptionGroup拥有value和displayName属性 value?: never; displayName?: never; }; export type Props = { name: string; label: string; options: (TOption | TOptionGroup)[]; };
此时你之前的无效对象会直接触发类型错误:
{ label: "Generation 1", displayName: "This shouldn't be valid", // 错误:类型“string”不能赋值给类型“undefined” options: [...], // 错误:类型“TOption[]”不能赋值给类型“undefined” value: "Generation 1", // 错误:类型“string”不能赋值给类型“undefined” }
这样就能严格限制每个数组元素只能是TOption或TOptionGroup中的一种,无法混合两者的核心属性。
补充:通用互斥工具类型(可选)
如果需要更通用的互斥类型约束,可以定义一个工具类型来自动生成互斥逻辑:
type ExcludeProps<T, U> = { [K in keyof U]?: never }; type MutuallyExclusive<T, U> = (T & ExcludeProps<T, U>) | (U & ExcludeProps<U, T>); // 此时Props的options可以改为: options: MutuallyExclusive<TOption, TOptionGroup>[];
不过对于你的场景,直接在类型中显式添加never属性已经足够清晰和实用。
内容的提问来源于stack exchange,提问作者Ollie
相关产品推荐
相关产品推荐

