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

TypeScript中如何根据其他属性值定义带附加属性的类型

TypeScript 实现带条件属性的SuperAnimal类型

原有写法的问题

之前的实现有两个核心错误:

  1. superpower被定义为可选属性,不符合「所有SuperAnimal必须包含superpower」的强制要求
  2. 单纯用交叉类型拼接Bird分支的写法,既没有覆盖非Bird类型的定义,也无法阻止非Bird类型携带cape属性,不满足「当且仅当type为Bird时需要cape」的规则

正确实现方案

用TS的可辨识联合类型即可实现需求,通过type字段作为辨识标签,拆分两种互斥的场景:

enum AnimalType {
  Cat = 'cat',
  Dog = 'dog',
  Lizard = 'lizard',
  Bird = 'bird',
}

type Animal = {
  type: AnimalType;
  name: string;
}

type SuperAnimal =
  // 非鸟类超级动物:无cape属性
  | (Omit<Animal, 'type'> & {
      type: Exclude<AnimalType, AnimalType.Bird>;
      superpower: string;
    })
  // 鸟类超级动物:必须带cape属性
  | (Omit<Animal, 'type'> & {
      type: AnimalType.Bird;
      superpower: string;
      cape: string;
    });

效果验证

以下用例可以验证类型规则完全生效:

// ✅ 合法:鸟类带cape
const birdHero: SuperAnimal = {
  type: AnimalType.Bird,
  name: 'Swift',
  superpower: 'supersonic flight',
  cape: 'crimson'
}

// ✅ 合法:猫不需要cape
const catHero: SuperAnimal = {
  type: AnimalType.Cat,
  name: 'Whiskers',
  superpower: 'night vision'
}

// ❌ 报错:非鸟类不允许带cape
const invalidCat: SuperAnimal = {
  type: AnimalType.Cat,
  name: 'Shadow',
  superpower: 'stealth',
  cape: 'navy'
}

// ❌ 报错:鸟类缺少cape
const invalidBird: SuperAnimal = {
  type: AnimalType.Bird,
  name: 'Hawk',
  superpower: 'wind control'
}

// ❌ 报错:所有SuperAnimal必须带superpower
const invalidDog: SuperAnimal = {
  type: AnimalType.Dog,
  name: 'Rex'
}

实现说明

  • Omit<Animal, 'type'>用来复用Animal类型中除type外的公共属性(这里是name),后续Animal新增公共属性时不需要重复修改SuperAnimal定义
  • Exclude<AnimalType, AnimalType.Bird>用来获取除Bird外的所有枚举值,对应不需要cape的分支
  • 联合类型会根据type字段的值自动收窄类型范围,严格约束cape属性的存在场景,完全满足互斥条件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 09:24:34