I'm using an interface in TypeScript to define a function that is only available on some of the classes that extend the base class. This is a simplified version of the code I have so far:
class Animal {
}
interface IWalkingAnimal {
walk(): void;
}
class Dog extends Animal implements IWalkingAnimal {
}
class Cat extends Animal implements IWalkingAnimal {
}
class Snake extends Animal {
}
private moveAnimal(animal: Animal) {
if (animal instanceof Cat || animal instanceof Dog) {
animal.walk();
}
}
Now, the trouble is I'll be adding more 'walking' animals so the moveAnimal functional will grow too large to be manageable. What I would like to do is something like this:
private moveAnimal(animal: Animal) {
if (animal implements IWalkingAnimal ) {
animal.walk();
}
}
However the 'implements' check does not work, and I cannot find an equivalent to 'instanceof' when using interfaces. In Java it seems that the use of 'instanceof' would work here, but TypeScript will not allow this.
Does such a thing exist in TypeScript, or is there a better approach here? I am using the TypeScript 1.8.9.
Unlike classes, interfaces exist only at compile-time, they are not included into the resulting JavaScript, so you cannot do an instanceof
check.
You could make IWalkingAnimal
a subclass of Animal (and use instanceof
), or you could check if the object in question has a walk
method:
if (animal['walk']) {}
You can wrap this in a user defined type guard (so that the compiler can narrow the type when used in an if
statement, just like with instanceof
).
/**
* User Defined Type Guard!
*/
function canWalk(arg: Animal): arg is IWalkingAnimal {
return (arg as IWalkingAnimal).walk !== undefined;
}
private moveAnimal(animal: Animal) {
if (canWalk(animal)) {
animal.walk(); // compiler knows it can walk now
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.