Recently I started using discrimination unions a lot in typescript. This technique allows us to write more type-safe codes, for instance:

interface Bird {
  name: "bird",
  fly(): void;
  layEggs(): void;
}

interface Fish {
  name: "fish",
  swim(): void;
  layEggs(): void;
}

declare function getSmallPet(): Fish | Bird;

let pet = getSmallPet();

This works:

pet.layEggs();

But not this:

pet.swim(); 
// Errors in code:
// Property 'swim' does not exist on type 'Bird | Fish'.
//   Property 'swim' does not exist on type 'Bird'.

This forces us to add additional checks to pass the compiler error:

if(pet.name === 'fish'){
  pet.swim(); // this will work
}

See more on typescriptlang.org/docs