Typescript 抽象 class 静态方法未强制执行

Typescript abstract class static method not enforced

我在 TypeScript 中有这个简单的代码:

abstract class Config {
    readonly NAME: string;
    readonly TITLE: string;

    static CoreInterface: () => any
}

class Test implements Config {
    readonly NAME: string;
    readonly TITLE: string;
}

即使 CoreInterface() 成员在 Test class 中丢失,TypeScript 也不会抱怨。为什么是这样?

我需要每个派生的 class 在 CoreInterface() 静态函数中提供一些关于自身的元数据。我知道我可以扩展 Config class 并让每个 sub-class 提供自己的 CoreInterface() 实现,但我不想要 sub-classes 自动继承配置的任何成员class。这就是为什么我使用 "implements" 而不是 "extends"

根据您的评论,您可以通过以下方式实现您的目标:

interface ConfigConstructor {
    CoreInterface: () => any;
    new (): Config;
}

interface Config {
    readonly NAME: string;
    readonly TITLE: string;
}

const Test: ConfigConstructor = class Test implements Config {
    readonly NAME: string;
    readonly TITLE: string;

    static CoreInterface = function (): any { return "something"; }
}

(code in playground)

如果您注释掉其中一个成员(即:NAME),您将收到此错误:

Class 'Test' incorrectly implements interface 'Config'.
Property 'NAME' is missing in type 'Test'.

如果你注释掉静态 CoreInterface 你会得到这个错误:

Type 'typeof Test' is not assignable to type 'ConfigConstructor'.
Property 'CoreInterface' is missing in type 'typeof Test'.


原回答

Static members/methods 不适用于继承(这对 OO 通常是正确的,而不是特定于打字稿)因为(正如@JBNizet 评论的那样)所有静态属性都属于 class 本身并且不是实例。

Wikipedia article中所写:

A static method can be invoked even if no instances of the class exist yet. Static methods are called "static" because they are resolved at compile time based on the class they are called on and not dynamically as in the case with instance methods, which are resolved polymorphically based on the runtime type of the object. Therefore, static methods cannot be overridden

同时查看此线程:Why aren't static methods considered good OO practice?

至于你想完成什么,你不会因为扩展class时没有实现静态方法而得到编译错误,但是你会得到运行时错误:

class A {
    static fn() {
        throw new Error("not implemented!");
    }
}

class B extends A {
    static fn() {
        console.log("B.fn");
    }
}

class C extends A { }

B.fn(); // ok
C.fn(); // error: not implemented!

(code in playground)