Typescript abstract class static method not enforc

2019-08-02 08:43发布

I have this simple code in TypeScript:

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

    static CoreInterface: () => any
}

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

Even though the CoreInterface() member is missing in the Test class, TypeScript does not complain. Why is this?

I need every derived class to provide some metadata about itself in the CoreInterface() static function. I know I could just extend the Config class and have each sub-class provide its own implementation of CoreInterface(), but I do not want sub-classes to automatically inherit any of the members of the COnfig class. That is why I use "implements" instead of "extends"

1条回答
我只想做你的唯一
2楼-- · 2019-08-02 08:46

Based on your comment, here's how you can achieve what you're looking for:

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)

If you comment out one of the members (i.e.: NAME) you'll get this error:

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

If you comment out the static CoreInterface you'll get this error:

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


Original answer

Static members/methods don't work with inheritence (that's true to OO in general and not specific to typescript) because (as @JBNizet commented) all static properties belong to the class itself and not to the instances.

As written in 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

Also check this thread: Why aren't static methods considered good OO practice?

As for what you want to accomplish, you won't be able to get compilation errors for not implementing the static method when extending the class, but you can get runtime errors:

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)

查看更多
登录 后发表回答