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

TypeScript实现接口互斥属性校验:限制仅能二选一分配子接口

TypeScript联合类型互斥属性校验问题

问题场景

我定义了三个TypeScript接口x、y、z,其中z的user字段为x | y联合类型。但创建z类型对象时,同时传入name和roll属性并未触发TypeScript错误,需要实现仅允许分配name或roll其中一个属性的校验逻辑,让非法赋值触发错误。

原接口代码:

interface x{
   id: number;
   name: string;
}

interface y{
   id: number;
   roll: string;
}

interface z{
   id: number;
   user: x | y;
}

当前无错误但需要触发报错的对象创建代码:

let temp: z = {
   id: 1,
   user: {
      id: 2,
      name: 'User',
      roll: '10'
   }
}

解决方案

TypeScript默认的联合类型允许同时包含两个类型的属性(因为联合类型是“或”的关系,但对象可以同时满足多个类型的结构),要实现互斥校验,需要让类型明确标记“对方的属性不存在”。

方法一:直接修改接口定义

给每个接口添加对方属性的never类型,明确禁止同时存在:

interface x {
  id: number;
  name: string;
  // 明确x类型不能有roll属性
  roll?: never;
}

interface y {
  id: number;
  roll: string;
  // 明确y类型不能有name属性
  name?: never;
}

interface z {
  id: number;
  user: x | y;
}

此时如果同时传入name和roll,TypeScript会检测到属性冲突,直接触发类型错误。

方法二:用工具类型封装互斥逻辑

如果不想修改原接口,可以通过工具类型自动生成互斥类型:

interface x {
  id: number;
  name: string;
}

interface y {
  id: number;
  roll: string;
}

// 生成互斥类型的工具类型
type MutuallyExclusive<T, U> = 
  (T & Partial<Record<keyof U, never>>) | 
  (U & Partial<Record<keyof T, never>>);

interface z {
  id: number;
  user: MutuallyExclusive<x, y>;
}

这个工具类型会自动给每个类型添加对方属性的never可选类型,实现和方法一相同的互斥校验效果。


内容的提问来源于stack exchange,提问作者Arifur Rahman Arif

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 02:32:06