我有一个抽象的基类和以下的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()
但遗憾的是我在这里做错了,因为我收到以下错误:
我对JS的类语法的细节仍然有点粗略,所以我不完全确定这是TS还是JS的东西。有人可以帮忙吗?
答案 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
已经被定义并且可以使用。