打字稿:扩展抽象类时的“ this”

时间:2019-05-08 10:36:20

标签: typescript

所以我的问题很简单。我有以下代码:

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

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

这应该意味着从A继承的任何类都应该在调用fn时返回其自身的实例,但是运行此代码会出现错误:Property 'fn' in type 'B' is not assignable to the same property in base type 'A'.

3 个答案:

答案 0 :(得分:2)

Titian解释了为什么不允许这样做。这是您以更安全的方式实现它的方法:

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

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

答案 1 :(得分:1)

您遇到的特定错误是由于您在fn中的B上没有注释而引起的。这意味着fn不会返回B this在派生类中。

您真正可以从返回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;
    }
}

答案 2 :(得分:0)

但是您不返回本身的实例,而是返回一个新实例:

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

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

或更改退货:

SELECT n.ID as articleID, n.title, n.content,
       COALESCE(MAX(r.state) FILTER (WHERE r.personid = 1), 'no state') as person_state,
       COUNT(*) FILTER (WHERE r.state = 'like') as num_likes,
       COUNT(*) FILTER (WHERE r.state = 'dislike') as num_dislikes
FROM News n LEFT JOIN
     Reaction r 
     ON n.ID = r.articleid
GROUP BY n.ID, n.title, n.content;