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

如何限制TypeScript联合类型子属性仅匹配指定接口?

实现严格匹配单个接口的类型约束

在TypeScript的结构类型系统中,普通联合类型允许对象满足至少一个类型的要求,哪怕它包含其他类型的属性。要实现严格匹配单个指定接口、禁止同时拥有多个接口属性的效果,可以通过以下两种方式实现:

方法一:手动为接口添加互斥属性约束

直接给每个接口定义另一个接口的属性,并将其类型设为never(可选属性用?: never),这样当对象同时包含多个接口的属性时,会直接触发类型错误:

interface Buz {
  buz: string;
  // 禁止拥有Qux的qux属性
  qux?: never;
}

interface Qux {
  qux: boolean;
  // 禁止拥有Buz的buz属性
  buz?: never;
}

export interface FooBar {
  content?: Buz | Qux;
}

// 错误示例:同时包含buz和qux,触发类型报错
const somethingBuz: FooBar = {
  content: {
    buz: 'yay!',
    qux: true // ❌ 类型“boolean”不能赋值给类型“undefined”
  }
}

const somethingQux: FooBar = {
  content: {
    buz: 'yay', // ❌ 类型“string”不能赋值给类型“undefined”
    qux: true
  }
}

// 合法示例
const validBuz: FooBar = {
  content: { buz: 'yay!' }
}

const validQux: FooBar = {
  content: { qux: true }
}

方法二:用泛型工具类型自动生成互斥联合类型

如果需要约束的接口数量较多,可以定义一个通用的StrictUnion工具类型,自动为联合类型中的每个成员添加互斥约束,无需手动修改每个接口:

interface Buz {
  buz: string;
}

interface Qux {
  qux: boolean;
}

// 工具类型:生成严格互斥的联合类型
type StrictUnion<T> = T extends any 
  ? T & Partial<Record<Exclude<keyof (UnionToIntersection<T>), keyof T>, never>> 
  : never;

// 辅助工具类型:将联合类型转为交叉类型
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;

export interface FooBar {
  content?: StrictUnion<Buz | Qux>;
}

// 错误示例:同时包含buz和qux,触发类型报错
const somethingBuz: FooBar = {
  content: {
    buz: 'yay!',
    qux: true // ❌ 类型“boolean”不能赋值给类型“undefined”
  }
}

const somethingQux: FooBar = {
  content: {
    buz: 'yay', // ❌ 类型“string”不能赋值给类型“undefined”
    qux: true
  }
}

// 合法示例
const validBuz: FooBar = {
  content: { buz: 'yay!' }
}

const validQux: FooBar = {
  content: { qux: true }
}

原理说明

  • 方法一中,通过给接口添加[其他接口属性]?: never的约束,强制对象不能同时拥有其他接口的属性,否则会触发类型不兼容的错误。
  • 方法二中,StrictUnion工具类型先通过UnionToIntersection获取联合类型所有成员的属性集合,再为每个成员排除不属于自身的属性,实现自动互斥的效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 21:25:21