为什么我不能在打字稿 class 的构造函数中访问抽象 属性
Why can't I access an abstract property in the constructor of a typescript class
abstract class Route {
abstract readonly name?: string;
protected abstract pattern: string;
public constructor() {
// Do something with `this.name` and `this.pattern`.
console.log(this.pattern); // Typecheck error
}
abstract handle(): void;
}
这会引发错误,因为 this.pattern
不会在构造函数中访问。为什么我不能访问它?
(将我的评论转换为答案)
Why can't I access it?
因为派生的class'构造函数不会被调用,所以对象可能处于无效状态。一些语言允许来自父构造函数的 virtual-calls 但它仍然被普遍认为是一种不好的做法。 TypeScript 选择不允许它。
文档中提到了这一点:https://www.typescriptlang.org/docs/handbook/classes.html
[...] each derived class that contains a constructor function must call super()
which will execute the constructor of the base class. What’s more, before we ever access a property on this in a constructor body, we have to call super()
. This is an important rule that TypeScript will enforce.
以防万一的解决方案是将pattern
作为参数传递给Route
的构造函数。如果 pattern
无法在调用父构造函数之前由子class' 构造函数确定,那么您需要重新考虑您的设计。
abstract class Route {
constructor(
private readonly pattern: string
)
{
console.log( pattern );
}
}
class Derived123 extends Route {
constructor() {
super( /*pattern:*/ "123" )
}
}
class Derived456 extends Route {
constructor() {
super( /*pattern:*/ "456" )
}
}
abstract class Route {
abstract readonly name?: string;
protected abstract pattern: string;
public constructor() {
// Do something with `this.name` and `this.pattern`.
console.log(this.pattern); // Typecheck error
}
abstract handle(): void;
}
这会引发错误,因为 this.pattern
不会在构造函数中访问。为什么我不能访问它?
(将我的评论转换为答案)
Why can't I access it?
因为派生的class'构造函数不会被调用,所以对象可能处于无效状态。一些语言允许来自父构造函数的 virtual-calls 但它仍然被普遍认为是一种不好的做法。 TypeScript 选择不允许它。
文档中提到了这一点:https://www.typescriptlang.org/docs/handbook/classes.html
[...] each derived class that contains a constructor function must call
super()
which will execute the constructor of the base class. What’s more, before we ever access a property on this in a constructor body, we have to callsuper()
. This is an important rule that TypeScript will enforce.
以防万一的解决方案是将pattern
作为参数传递给Route
的构造函数。如果 pattern
无法在调用父构造函数之前由子class' 构造函数确定,那么您需要重新考虑您的设计。
abstract class Route {
constructor(
private readonly pattern: string
)
{
console.log( pattern );
}
}
class Derived123 extends Route {
constructor() {
super( /*pattern:*/ "123" )
}
}
class Derived456 extends Route {
constructor() {
super( /*pattern:*/ "456" )
}
}