I've recently returned to JS/TS after coding a lot in Rust and this is a feature I really miss.
So suppose that I have a value which may be an instance of Cat or an instance of Dog and depending on which class it is from, I want to perform different logic. Since Javascript cannot do classname == (I think?), what I usually rely on is also passing a string indicating the class like this:
function groomAnimal(animal: Cat | Dog, animalType: 'cat' | 'dog') {
if (animalType === 'cat') {
(animal as Cat).trimNails();
} else {
(animal as Dog).trimFur();
}
}
I hate this because it's unwieldy and the compiler cannot guarantee that the caller correctly fulfills the contract. On the other hand, in Rust this would be quite elegant:
enum Animal {
Cat(CatData),
Dog(DogData),
}
fn groomAnimal(animal: Animal) {
match animal {
Cat(catData) => catData.trimNails(),
Dog(dogData) => dogData.trimFur(),
}
}
Basically, the enum itself which indicates the "class", also holds the "class" data and thus obtaining the data and checking the data type are the same operation
Is there any pattern in typescript that allows for polymorphic function signatures while ensuring at compile time that the code operates on the correct data types?