I got some typescript interface, abstract class and implementing sub-classes:
// Animal classes
abstract class Animal {
abstract sound(): string;
constructor(public name: string) {
}
eat(food: string): string {
return "I eat this now: " + food;
}
}
class Snake extends Animal{
constructor() {
super("Snake");
}
sound() {
return "Sssssss";
}
}
class Owl extends Animal{
constructor() {
super("Owl");
}
sound() {
return "Hu-huu";
}
// Owl can also fly!
fly() {
return "I can flyyyy";
}
}
// Box classes
interface BoxInterface {
animal: Animal;
}
class Box implements BoxInterface {
animal: Animal;
constructor(animal: Animal) {
this.animal = animal;
}
}
As you can see the idea is that we have a Box
and some kind of Animal
in the box - in our example it can be Snake
or Owl
.
Now we can create Box
with Owl
inside.
let box = new Box( new Owl() );
And now the problem - using any method declared in superclass is completely fine:
box.animal.sound(); // this is fine
but as you can see Owl have additional function fly()
and because fly is not declared in Animal
it throw:
box.animal.fly(); // Property 'fly' does not exist on type 'Animal'.
Also the same happens when creating normal variable:
let animal:Animal;
animal = new Owl();
animal.fly();
As addition Animal class do not have to be abstract, it can be normal class or interface - result will be the same.
My question is: why typescript throw it if my class is superset of other class. I think the main idea of interfaces and typing is guaranteeing that object has some properties like eat()
or sound()
in this example.
Im very new in typescript so it can be that I missed something, anyway how I can achieve that some variable must be some type but allowing additional methods in subclasses?