在 TypeScript 的 subclasses 中引用不带名称的 class 以使用不同的静态方法

Referencing class without name to use different static method in subclasses in TypeScript

在 ES6 中,您可以通过 this.constructor:

引用静态方法
class MainClass {
  static info() {
    return "This is some information";
  }
  constructor() {
    this.info = this.constructor.info(); // Allows subclass to define different '.info()' method.
  }
}

class ChildClass extends MainClass {
  static info() {
    return "This information is from the child";
  }

  constructor() {
    super();
  }
}

有没有办法在 TypeScript 中做到这一点?我希望能够覆盖 super class 的静态方法并从 subclass 使用它,而无需在实例方法中重新定义引用。现在,我知道如何在 TypeScript 中访问静态方法的唯一方法是使用 class 名称。

MainClass.info();

但如果我这样做,subclass 将继续使用 MainClass.info(); 而不是它自己的 .info() 方法。

检查此打字稿代码:

class MainClass {
  static info() {
    return "This is some information";
  }
  info: string;

  constructor() {
    this.info = (this.constructor as any).info(); // Allows subclass to define different '.info()' method.
  }
}

class ChildClass extends MainClass {
  static info() {
    return "This information is from the child";
  }

  constructor() {
    super();
  }
}

如果编译目标是 ES6,这将编译为您上面给出的代码并且工作正常。如果编译为 ES5,它也可以正常工作。

请注意,我使用了 as any hack 来允许在 constructor 函数上调用 .info()

或者,您可以在每个子 class 中覆盖 this.info 的设置。这样你就不需要黑客了。

这个怎么样:

interface MainClassConstructor {
    new (): MainClass;
    info(): string;
}

class MainClass {
    static info() {
        return "This is some information";
    }

    private info: string;

    constructor() {
        this.info = (this.constructor as MainClassConstructor).info(); // Allows subclass to define different '.info()' method.
    }
}

class ChildClass extends MainClass {
    static info() {
        return "This information is from the child";
    }

    constructor() {
        super();
    }
}

(code in playground)


编辑

你也可以使用typeof MainClass代替我添加的MainClassConstructor接口:

class MainClass {
    static info() {
        return "This is some information";
    }

    private info: string;

    constructor() {
        this.info = (this.constructor as typeof MainClass).info(); // Allows subclass to define different '.info()' method.
    }
}

此外还有一个 discussion/suggestion this.constructor 在这里返回正确的类型:T.constructor should be of type T.

另一种选择是使用方法覆盖:

class MainClass {
    private info: string;

    constructor() {
        this.info = this.getInfo();
    }

    protected getInfo(): string {
        return "This is some information";
    }
}

class ChildClass extends MainClass {
    constructor() {
        super();
    }

    protected getInfo(): string {
        return "This information is from the child";
    }
}