Typescript 打字稿:';这';扩展抽象类时

Typescript 打字稿:';这';扩展抽象类时,typescript,Typescript,所以我的问题很直截了当。我有以下代码: 抽象类A{ 公开摘要fn():此; } B类扩展了A类{ 公共fn(){ 返回新的B(); } } 这意味着,当调用fn时,从A继承的任何类都应该返回自身的实例,但运行此代码时,我得到一个错误:类型“B”中的属性“fn”不可分配给基类型“A”中的同一属性。但您没有返回自身的实例,您正在返回一个新实例: abstract class A { public abstract fn(): this; } class B extends A { pub

所以我的问题很直截了当。我有以下代码:

抽象类A{
公开摘要fn():此;
}
B类扩展了A类{
公共fn(){
返回新的B();
}
}

这意味着,当调用
fn
时,从A继承的任何类都应该返回自身的实例,但运行此代码时,我得到一个错误:
类型“B”中的属性“fn”不可分配给基类型“A”中的同一属性。

但您没有返回自身的实例,您正在返回一个新实例:

abstract class A {
  public abstract fn(): this;
}

class B extends A {
  public fn() {
    return this;
  }
}
或更改报税表:

abstract class A {
  public abstract fn(): A;
}

class B extends A {
  public fn() {
    return new B();;
  }
}

您得到的特定错误是由于您在
B
中的
fn
上没有注释造成的。这意味着
fn
将在派生类中返回
B
而不是

从返回
this
的函数中真正可以返回的唯一值(无类型断言)是
this
。考虑以下事项:

abstract class A {
    public abstract fn(): this;
}

class B extends A {
    public fn(): this {
        return new B();
    }
}

class C extends B {
    m() { }
}
new C().fn().m(); // runtime error since fn returned B instead of C
您可以使用类型断言,但它不是真正的类型安全的,如上所示:

class B extends A {
    public fn(): this {
        return new B() as this;
    }
}

提香解释了为什么不允许这样做。以下是如何以更安全的方式实施它:

abstract class A<T> {
    public abstract fn(): T;
}

class B extends A<B> {
    public fn() {
        return new B();
    }
}
抽象类A{
公开摘要fn():T;
}
B类扩展了A类{
公共fn(){
返回新的B();
}
}

这是一个很好的解释,非常感谢!我想我必须改变代码的结构,因为正如你所说的,没有一个好的类型安全的方法来实现我想要的。我也会接受答案,所以让我告诉你。@Komninos你基本上想正确键入一个
clone
函数。我不认为有一个好的方法可以在typescript中对此进行建模。函数的类型必须确保所有派生类型都必须重写它,
abstract
只会使您重写一级类。是的,这是类型安全的,但无法将其扩展到
B
:(