When you have an union type and you want to infer one of the type, the common way is using type guard
interface Bird {
fly();
layEggs();
}
interface Fish {
swim();
layEggs();
}
function getSmallPet(pet: Fish | Bird) {
// use a type guard function
if (isFish(pet)) {
// inside this block, pet is Fish type
return pet.swim();
}
return pet.fly();
}
// create a type guard function
function isFish(pet: Fish | Bird): pet is Fish {
return (pet as Fish).swim !== undefined;
}
But since Typescript 2.7, we could use in
operator which give us simpler code without need to create a function.
function getSmallPet(pet: Fish | Bird) {
if ("swim" in pet) {
return pet.swim(); // pet: Fish
}
...
}
Easy peasy!