I'm trying to create a set that will allow me to add ONLY concrete sub classes of an abstract class. Looking at similar questions here, I was able to reach a point where I see an error whenever I try to add the abstract class or other random classes.
The problem occurs when I "trick" the compiler and implements a class with the same function as my abstract class. TSC can't tell the difference between a class that extends the abstract class and just a class that implements a function:
abstract class Animal {
walk(){}
}
class Dog extends Animal {
override walk() {console.log("");}
}
class ServiceDog extends Dog {
override walk() {console.log("")}
}
class Cat extends Animal {
override walk() {console.log("");}
}
class Person {
walk() {console.log("♂️");}
}
const map: Map<string, new () => Animal> = new Map();
map.set("dog", Dog); // All good
map.set("animal", Animal); // throws an error
map.set("person", Person); // accepts it <-- HERE I WANT TO GET AN ERROR
If I'll remove the walk() function from class Person it would show Argument of type 'typeof Person' is not assignable to parameter of type 'new () => Animal'. Property 'walk' is missing in type 'Person' but required in type 'Animal'.
Which makes me wonder - Does Typescript only checks classes' inheritance by their properties and functions? Is there a way to enforce it base on the extends word?
Thanks