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

TypeScript:如何扩展基类并收窄animal属性的type为Dog?

实现DogOwner类的两种方法

首先得补全Dog、Cat、Fish的类型定义(原代码未给出,这里提供基础示例):

type Dog = { breed: string };
type Cat = { hasClaws: boolean };
type Fish = { waterType: 'fresh' | 'salt' };

推荐方案:泛型基类

把AnimalOwner改成泛型抽象类,让子类指定具体的动物类型,能安全收窄animal的类型:

abstract class AnimalOwner<T extends Animal> {
    public name: string;
    public animal: T;

    constructor(name: string, animal: T) {
        this.name = name;
        this.animal = animal;
    }
}

type Animal = {
    type: Dog | Cat | Fish,
    foo: string,
    bar: string,
};

// 定义DogOwner,指定泛型为type仅含Dog的Animal类型
class DogOwner extends AnimalOwner<Omit<Animal, 'type'> & { type: Dog }> {
    // 可在此添加DogOwner专属的方法或属性
}

// 使用示例
const goldenRetriever = {
    type: { breed: 'Golden Retriever' },
    foo: 'woof',
    bar: 'good boy'
};
const alice = new DogOwner('Alice', goldenRetriever);
// 此时alice.animal.type的类型自动收窄为Dog

备选方案:重写属性收窄类型

如果无法修改原基类,直接在DogOwner里重写animal属性,明确指定其type为Dog:

abstract class AnimalOwner {
    public name: string;
    public animal: Animal;

    constructor(name: string, animal: Animal) {
        this.name = name;
        this.animal = animal;
    }
}

type Animal = {
    type: Dog | Cat | Fish,
    foo: string,
    bar: string,
};

class DogOwner extends AnimalOwner {
    // 重写animal属性,收窄type为Dog
    public animal: Omit<Animal, 'type'> & { type: Dog };

    constructor(name: string, animal: typeof DogOwner.prototype.animal) {
        super(name, animal);
        this.animal = animal;
    }
}

补充说明

  • 泛型方案更灵活,后续新增CatOwner、FishOwner时可直接复用基类,类型检查更严谨。
  • 重写属性的方案适合无法改动原基类的场景,但要保证子类的animal类型是基类Animal的子类型,避免类型冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 02:50:29