Typescript 正确推断超类中的动态子类

Typescript 正确推断超类中的动态子类,typescript,Typescript,假设我们有一个简单的继承案例: class Animal { // Return a shallow copy with all prototype functions getClone(): Animal { return Object.assign(Object.create(Object.getPrototypeOf(this)), this); } } class Dog extends Animal { woof() { console.log('Woof')

假设我们有一个简单的继承案例:

class Animal {
  // Return a shallow copy with all prototype functions
  getClone(): Animal {
    return Object.assign(Object.create(Object.getPrototypeOf(this)), this);
  }
}

class Dog extends Animal {
  woof() { console.log('Woof'); }
}
因此,乍一看,这段代码运行良好。但是,当我尝试从Dog实例使用
getClone()
时:

const dog = new Dog();
// Invalid since the superclass Animal doesn't contain the function woof()
dog.getClone().woof();
当然,我总是可以通过以面向对象的方式重写getClone()来修复此错误:

class Dog extends Animal {
  woof() { console.log('Woof'); }
  getClone(): Dog {
    return super.getClone();
  }
}
但假设这个项目规模扩大了,我需要创建100个动物类。在每个类中编写重写函数是否会如此麻烦?另外,如果我需要向基础Animal类添加一个函数,我是否需要在每个子类中重载它

所以,我想出了一个临时解决方案:使用泛型

class Animal<T> {
  getClone(): T {
    return Object.assign(Object.create(Object.getPrototypeOf(this)), this);
  }
}

class Dog extends Animal<Dog> {
  woof() { console.log('Woof'); }
}
似乎Typescript没有认识到T是动物的一个子类,我正试图找到一种方法使它正常工作。请注意,
class Animal
也不起作用。有一种方法可以解决这个问题,因为我可以说,
将它作为任何一种
返回,但归根结底,这只是一种解决方法


那么,你们认为什么是解决这类问题的正确方法呢?

通常使用泛型方法,因为在大多数语言中,无法告诉基类中的方法它返回的是当前的类型。幸运的是,Typescript不是大多数语言。Typescript允许在非静态方法中将此用作类型,这正是您所需要的:

class Animal {
    // Return a shallow copy with all prototype functions
    getClone(): this {
        return Object.assign(Object.create(Object.getPrototypeOf(this)), this);
    }
}

class Dog extends Animal {
    woof() { console.log('Woof'); }
}

new Dog().getClone().woof();
这是介绍该功能的最新版本

class Animal {
    // Return a shallow copy with all prototype functions
    getClone(): this {
        return Object.assign(Object.create(Object.getPrototypeOf(this)), this);
    }
}

class Dog extends Animal {
    woof() { console.log('Woof'); }
}

new Dog().getClone().woof();