Type guards are runtime checks that narrow types within conditional blocks. Built-in guards include typeof, instanceof, and in operators. Custom type guards are functions returning a type predicate (param is Type) to narrow types based on custom logic.
Built-in Type Guards:
typeof: For primitives (string, number, boolean, etc.)instanceof: For class instancesin: For checking property existence=== null, !== undefinedCustom Type Guards:
param is TypeWhy Use Type Guards:
// typeof guard for primitives
function process(value: string | number) {
if (typeof value === 'string') {
console.log(value.toUpperCase()); // value is string
} else {
console.log(value.toFixed(2)); // value is number
}
}
// instanceof guard for classes
class Dog { bark() { return 'woof'; } }
class Cat { meow() { return 'meow'; } }
function speak(animal: Dog | Cat) {
if (animal instanceof Dog) {
console.log(animal.bark()); // animal is Dog
} else {
console.log(animal.meow()); // animal is Cat
}
}
// 'in' operator guard
interface Fish { swim: () => void; }
interface Bird { fly: () => void; }
function move(animal: Fish | Bird) {
if ('swim' in animal) {
animal.swim(); // animal is Fish
} else {
animal.fly(); // animal is Bird
}
}