为什么我无法访问打字稿类的构造函数中的抽象属性

sou*_*ubi 11 class abstract typescript

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;
}
Run Code Online (Sandbox Code Playgroud)

这会引发错误,因为this.pattern不会在构造函数中访问。为什么我无法访问它?

Dai*_*Dai 12

(将我的评论转换为答案)

\n
\n

为什么我无法访问它?

\n
\n

因为派生类\xe2\x80\x99的构造函数不会\xe2\x80\x99被调用,所以该对象可能处于无效状态。某些语言允许来自父构造函数的虚拟调用,但它\xe2\x80\x99s仍然普遍认为是一种不好的做法。TypeScript 选择禁止它。

\n

文档中提到了这一点:https ://www.typescriptlang.org/docs/handbook/classes.html

\n
\n

[...]每个包含构造函数的派生类都必须调用super()它将执行基类的构造函数。更重要的是,在我们在构造函数体中访问 this 的属性之前,我们必须调用super(). 这是 TypeScript 将强制执行的一条重要规则。

\n
\n

万一的解决方案是将pattern作为参数传递给Route\ 的构造函数。如果pattern在调用父构造函数之前无法通过 subclass\xe2\x80\x99 构造函数确定,那么您需要重新考虑您的设计。

\n
abstract class Route {\n    \n    constructor(\n        private readonly pattern: string\n    )\n    {\n        console.log( pattern );\n    }\n}\n\nclass Derived123 extends Route {\n    \n    constructor() {\n        super( /*pattern:*/ "123" )\n    }\n}\n\nclass Derived456 extends Route {\n    \n    constructor() {\n        super( /*pattern:*/ "456" )\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n