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"
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)