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

TypeScript联合类型数组:如何识别类型并拦截非法属性组合

解决TypeScript联合类型允许非法交叉对象的问题

要让同时包含IMenuItem和IMenuDivider属性的对象触发类型错误,核心是把原来的“包容型联合类型”改成互斥型联合类型,有两种常用方案:

方案1:添加鉴别属性(推荐)

给每个接口添加一个唯一的type属性作为鉴别标识,让TypeScript能明确区分不同类型的成员,自然排除交叉情况:

// 修改后的接口
interface IMenuItem {
  type: 'item'; // 唯一鉴别值
  label: string;
  onClick: () => void;
}

interface IMenuDivider {
  type: 'divider'; // 唯一鉴别值
}

// 互斥的联合类型
type TItem = IMenuItem | IMenuDivider;

此时如果传入同时包含两类属性的对象:

// 会触发类型错误:不存在同时满足type: 'divider'和label/onClick的类型
const invalidItem: TItem = { type: 'divider', label: 'Test', onClick: () => {} };

方案2:用never排除交叉属性

如果不想新增鉴别属性,可以通过交叉never类型,强制每个类型不能包含另一类型的核心属性:

// 原接口保持不变
interface IMenuItem {
  label: string;
  onClick: () => void;
}

interface IMenuDivider {
  type: 'divider';
}

// 定义互斥联合类型:每个分支排除另一类型的属性
type TItem = 
  | (IMenuItem & { type?: never }) // 不允许有type属性
  | (IMenuDivider & { label?: never; onClick?: never }); // 不允许有label/onClick属性

此时传入交叉对象会直接报错,因为没有分支能匹配同时拥有两类属性的结构。

原理说明

TypeScript默认的联合类型是“包容式”的——只要对象满足联合类型中至少一个成员的结构,就会被判定为合法。通过上述两种方式,我们把联合类型改成了“互斥式”:对象必须严格匹配其中一个成员的结构,不能同时满足多个。

内容的提问来源于stack exchange,提问作者Uri Klar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 16:24:20