I have made a factory that will create instances of certain classes. I want to use generics to ensure that all of the objects returned are from sub-classes that extend an abstract classes.
I thought that the logic of the createInstance method shown below could be described as 'createInstance() will return a type T that is constrained to be a class that extends Animal.
As you can see, Lion extends Animal, but I still get the compiler warning type Lion is not assignable to type T.
abstract class Animal {
abstract makeSound(): void;
}
class Bear extends Animal {
public makeSound() {
console.log('growl');
}
}
class Lion extends Animal {
public makeSound() {
console.log('roar');
}
}
function createInstance<T extends Animal>(type: string): T {
switch(type) {
case 'bear':
return new Bear(); // 'type Bear is not assignable to type T'
case 'lion':
return new Lion(); // 'type Lion is not assignable to type T'
}
}
createInstance().makeSound();
I have read at the end of the TypeScript Generics docs that:
When creating factories in TypeScript using generics, it is necessary to refer to class types by their constructor functions. For example,
function create<T>(c: {new(): T; }): T { return new c(); }
but I don't really want to have to pass in the class constructor into the function if possible and would like to understand why I'm getting the not assignable to type T message in the first place.
Thanks