You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 00:47:48