Typescript:在调用super之前从基类构造函数访问继承类的静态属性?

时间:2018-01-11 03:07:56

标签: node.js typescript

我有一个抽象的错误类,用于继承服务错误,使错误处理更容易一些。 (ErrorBase来自https://gist.github.com/justmoon/15511f92e5216fa2624b#gistcomment-1928632

export abstract class ServiceError extends ErrorBase {
  abstract statusCode(): number;
  abstract readonly errorCode: string;
  static readonly defaultMessage: string;
  constructor(readonly context?: any, message?: string) { super(message); }

  toJSON(key: any) {
    return {
      errorCode: this.errorCode,
      message: this.message,
      context: this.context
    };
  }    
}

这是一个扩展它的类的例子:

export class ExampleError extends ServiceError {
  statusCode(): number { return 400; }
  errorCode: string = "err-example";
  static readonly defaultMessage = "This is an example error";
  constructor(context?: any, message?: string) {
    super(context, message ? message : ExampleError.defaultMessage);
  }
}

我一直试图找到一种方法从基类的构造函数内部访问继承类的defaultMessage,这样我就可以简化继承类的构造函数。我有什么方法可以做到这一点吗?

2 个答案:

答案 0 :(得分:0)

静态属性只是原型函数中定义的属性。他们编译如下:

// TypeScript
class A {
    public static property = 'my string';
}

// Compiled ES5 JavaScript
function A() {}
A.property = 'my string';

因此,您可以使用this上的constructor属性来访问用于构造实例(或者更确切地说是复制)的派生类/函数:

class A {
    public static defaultMessage = 'My Error A';
    constructor() {
        // will output "My Error B" if a instance of B is being constructed
        console.log(this.constructor['defaultMessage']);
    }
}

class B {
    public static defaultMessage = 'My Error B';
}

答案 1 :(得分:0)

格雷格的回答是正确的,您应该使用this.constructor。由于this issue中说明的原因,您必须将其强制转换为typeof ServiceError。这很复杂,但是简短的版本是您不能在基类中说出有关子类的构造函数的形状的任何内容-Base可以包含constructor(),而Sub可以包含{ {1}} -这意味着constructor(string, number)必须输入this.constructor才能提出更好的主意。

之所以起作用,是因为静态赋值是在调用任何构造函数之前先从基类然后是子类运行的,然后再调用子类构造函数,但必须立即调用其父构造函数。父级的所有属性分配都在构造函数主体之前运行,然后父级构造函数运行,然后在Function调用之后返回子级构造函数。

如果我正确理解了您的问题,这应该可以满足您的要求:

super()

Playground version