Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript abstract class static method not enforced

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"

like image 857
prmph Avatar asked May 01 '17 17:05

prmph


1 Answers

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)

like image 116
Nitzan Tomer Avatar answered Sep 25 '22 12:09

Nitzan Tomer