Skip to content

pet is Fish ‐ type predicates

Daisho Komiyama edited this page Apr 17, 2024 · 2 revisions
// set up
class Fish {
  swim() {}
}

class Bird {
  fly() {}
}

function getSmallPet() {
  if (Math.random() > .5) {
    return new Fish()
  } else {
    return new Bird()
  }
}

With type predicates

Type predicates: pet is Fish is not a function return type. It ensures the parameter type is Fish after the function call.

// Type predicate narrows the parameter pet after this function call
function isFish(pet: Fish | Bird): pet is Fish {
  return (pet as Fish).swim !== undefined;
}

// application
const pet = getSmallPet();
 
if (isFish(pet)) {
  pet.swim();
} else {
  pet.fly();
}

Without type predicates

Without type predicates, type guards like 'swim' in pet are required before use.

// no type predicates
function isFish(pet: Fish | Bird) {
  return (pet as Fish).swim !== undefined;
}

// application
const pet = getSmallPet();
 
if (isFish(pet)) {
  pet.swim();
    // ^ Property 'swim' does not exist on type 'Bird'.
} else {
  pet.fly();
    // ^ Property 'fly' does not exist on type 'Fish'.
}

Type predicates simplify type checks, ensuring the correct usage of properties without the need for additional guards.

Clone this wiki locally