I have an interface which is extending another one. Now I am trying to put a variable of the superinterface type into a function that needs a subinterface type parameter. This is not possible as the superinterface typed variable is missing certain attributes.
It's a little hard to explain, so I've created an example with an Animal
interface, which is extended by a Horse
interface:
interface Animal {
age:number;
//... 100 other things
}
interface Horse extends Animal {
speed:number;
}
Now I have a module with one private function (rideHorse
), which only accepts a Horse
as parameter. And a public function (rideAnimal
), accepting all Animal
s like below:
module AnimalModule {
function rideHorse(horse:Horse) {
alert(horse.speed);
}
export function rideAnimal(animal:Animal) {
animal.speed = 10; // Error: Animal cannot have speed
rideHorse(animal); // Error: 'animal' needs speed
}
}
// Calling the rideAnimal function
var myAnimal:Animal = {
age: 10
};
AnimalModule.rideAnimal(myAnimal);
As you can see this is not working because the animal
parameter of rideAnimal
doesn't have speed
. So my question is: How can I cast my animal
into a Horse
and add speed
manually inside the rideAnimal
function, so the errors will disappear?
You can cast your Animal
into a Horse
like this.
function rideAnimal(animal:Animal) {
var horse = animal as Horse;
horse.speed = 10;
rideHorse(horse);
}
Yes, you can use user defined type guards to handle this kind of custom type evaluation:
interface Animal
{
age: number;
//... 100 other things
}
interface Horse extends Animal
{
speed: number;
}
module AnimalModule
{
function rideHorse(horse: Horse)
{
alert(horse.speed);
}
function isHorse(a: Animal): a is Horse
{
return "speed" in a;
}
export function rideAnimal(animal: Animal)
{
if (isHorse(animal))
{
animal.speed = 10; // Ok
rideHorse(animal); // Ok
} else
throw new Error("You can only ride horses")
}
}
If Horse
and Animal
were classes, you could have just done if (animal instanceof Horse)
instead of using the custom type guard isHorse
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With