抽象方法在构造函数中不可调用

时间:2018-06-10 07:22:58

标签: javascript typescript

我有一个抽象的基类和以下的prop定义和构造函数:

protected abstract connectToFirebase: (config: any) => Promise<void>;
protected abstract listenForConnectionStatus: () => void;

constructor(config: IFirebaseConfig = {}) {
  if (config.mocking) {
    this._mocking = true;
    this.getFireMock();
  } else {
    this._mocking = false;
    this.connectToFirebase(config).then(() => this.listenForConnectionStatus());
  }
}

我希望具体的子类必须定义connectToFirebase()listenForConnectionStatus()但遗憾的是我在这里做错了,因为我收到以下错误:

enter image description here

我对JS的类语法的细节仍然有点粗略,所以我不完全确定这是TS还是JS的东西。有人可以帮忙吗?

1 个答案:

答案 0 :(得分:1)

您需要将其声明为抽象方法而不是抽象属性:

protected abstract connectToFirebase(config: any): Promise<void>;
protected abstract listenForConnectionStatus: () => void;

constructor(config: IFirebaseConfig = {}) {
    this.connectToFirebase(config).then(() => this.listenForConnectionStatus());
}

之所以可以将listenForConnectionStatus声明为抽象属性是因为它是在箭头函数中调用的。如果您尝试执行此操作,则会得到一个错误:

// Abstract property 'listenForConnectionStatus' in class 'Foo' cannot be accessed in the constructor.
this.connectToFirebase(config).then(this.listenForConnectionStatus);

两者之间存在差异的原因在于它们的实例化方式。

当声明为属性时,扩展基类的类将如下所示:

var Concrete = /** @class */ (function (_super) {
    __extends(Concrete, _super);
    function Concrete() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.connectToFirebase = function (config) { return null; };
        return _this;
    }
    return Concrete;
}(Base));

如您所见,它将调用super,然后然后设置_this.connectToFirebase,因此,在调用super时,this.connectToFirebase将是{{ 1}}。

将此与已编译的JavaScript进行比较,以获得抽象的方法

undefined
在声明构造函数的同时,在var Concrete = /** @class */ (function (_super) { __extends(Concrete, _super); function Concrete() { return _super !== null && _super.apply(this, arguments) || this; } Concrete.prototype.connectToFirebase = function (config) { return null; }; return Concrete; }(Base)); 上声明

connectToFirebase。这意味着在实际调用构造函数时,它会调用prototype,但是super已经被定义并且可以使用。