I have the following objects and classes that demonstrate dependency injection:
abstract class Animal {
speak(): void {};
}
class Dog implements Animal {
speak(): void {
console.log('Woof woof');
}
}
class Cat implements Animal {
speak(): void {
console.log('Meow meow');
}
}
class PetOwner {
pet: Animal
constructor({ pet = new Dog() }: { pet?: Animal } = {}) {
this.pet = pet;
}
communicate(): void {
this.pet.speak();
}
}
const owner1 = new PetOwner();
owner1.communicate(); // Woof woof
const owner2 = new PetOwner({ pet: new Cat() });
owner2.communicate(); // Meow meow
The above scenario works well as expected.
However, there is a strange occurrence...
class Parrot {
speak() {
console.log('Should not be possible, but it is.')
}
}
const owner3 = new PetOwner({ pet: new Parrot() });
owner3.communicate(); // Should not be possible, but it works.
Why does TypeScript allow passing in a Parrot
object when both the pet
attribute in the PetOwner
class and the pet
parameter in the constructor are specified as type Animal
?