You need to enable JavaScript to run this app. TypeScript如何基于类实例的animalType值实现config属性的类型守卫
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript如何基于类实例的animalType值实现config属性的类型守卫

解决方案

要实现类实例的属性关联类型收窄,核心是把animalType和config的类型做绑定,打破原来两个独立联合类型的无关联状态,有两种常用实现方式:


方式1:复用现有可辨识联合类型(和你之前对象实现逻辑完全对齐)

直接复用你已经定义好的Smth联合类型,通过构造函数重载+类型断言,让类的实例完全符合可辨识联合的规则:

enum Animal {
  BIRD = 'bird',
  DOG = 'dog',
}

type Base = {
    id: number
}

type Smth = Base &
  (
    | {
        animalType: Animal.BIRD;
        config: number;
      }
    | {
        animalType: Animal.DOG;
        config: string;
      }
  );

// 内部实现类
class _MyClass {
  id: number;
  animalType: Animal;
  config: number | string; 

  // 构造函数重载,保证初始化时类型就合法
  constructor(id: number, animalType: Animal.BIRD, config: number);
  constructor(id: number, animalType: Animal.DOG, config: string);
  constructor(id: number, animalType: Animal, config: number | string) {
    this.id = id;
    this.animalType = animalType;
    this.config = config;
  }
}

// 导出的类类型对齐Smth联合类型
type MyClass = Smth;
const MyClass = _MyClass as {
  new (id: number, animalType: Animal.BIRD, config: number): MyClass;
  new (id: number, animalType: Animal.DOG, config: string): MyClass;
};

使用效果:

const smthClass = new MyClass(1, Animal.BIRD, 1);
if (smthClass.animalType === Animal.BIRD) {
  smthClass.config = 1;
  smthClass.config = 'x'; // 触发类型错误,符合预期
}

方式2:泛型条件类型实现(写法更简洁)

通过泛型参数绑定两个属性的类型关系,无需额外定义联合类型:

enum Animal {
  BIRD = 'bird',
  DOG = 'dog',
}

class MyClass<T extends Animal> {
  id: number;
  animalType: T;
  // 用条件类型把config类型和animalType做绑定
  config: T extends Animal.BIRD ? number : string; 

  constructor(id: number, animalType: T, config: T extends Animal.BIRD ? number : string) {
    this.id = id;
    this.animalType = animalType;
    this.config = config;
  }
}

使用效果和方式1完全一致:

const smthClass = new MyClass(1, Animal.BIRD, 1);
if (smthClass.animalType === Animal.BIRD) {
  smthClass.config = 1;
  smthClass.config = 'x'; // 触发类型错误
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 09:09:03