Skip to main content

Archive

Show more

Type Guards in TypeScript

Type Guards in TypeScript

Type guards in TypeScript are mechanisms that allow you to narrow down the type of a variable within a certain scope. This helps ensure type safety by allowing TypeScript to infer more specific types when certain conditions are met.


Basic Type Guards

Type guards are commonly used to perform type checking and narrow down types based on conditions. Here are some basic examples:

Using typeof

The typeof operator can be used to check the type of a variable:


function printLength(value: string | number) {
  if (typeof value === "string") {
    console.log(`String length: ${value.length}`);
  } else {
    console.log(`Number: ${value}`);
  }
}

printLength("Hello"); // Output: String length: 5
printLength(42);      // Output: Number: 42

Using instanceof

The instanceof operator checks if an object is an instance of a particular class:


class Dog {
  bark() {
    console.log("Woof!");
  }
}

class Cat {
  meow() {
    console.log("Meow!");
  }
}

function makeSound(animal: Dog | Cat) {
  if (animal instanceof Dog) {
    animal.bark();
  } else {
    animal.meow();
  }
}

makeSound(new Dog()); // Output: Woof!
makeSound(new Cat()); // Output: Meow!

Using in Operator

The in operator checks if a property exists in an object:


interface Bird {
  fly: () => void;
}

interface Fish {
  swim: () => void;
}

function move(animal: Bird | Fish) {
  if ("fly" in animal) {
    animal.fly();
  } else {
    animal.swim();
  }
}

let bird: Bird = { fly: () => console.log("Flying") };
let fish: Fish = { swim: () => console.log("Swimming") };

move(bird); // Output: Flying
move(fish); // Output: Swimming

Type Predicates

Type predicates are a way to specify the type of a variable within a custom type guard function:


function isString(value: any): value is string {
  return typeof value === "string";
}

function print(value: string | number) {
  if (isString(value)) {
    console.log(`String value: ${value}`);
  } else {
    console.log(`Number value: ${value}`);
  }
}

print("Hello"); // Output: String value: Hello
print(42);      // Output: Number value: 42

Conclusion

Type guards are essential for ensuring type safety in TypeScript by allowing you to narrow down types based on conditions. By utilizing operators like typeof, instanceof, and in, as well as creating custom type guard functions with type predicates, you can write more robust and error-free code. Understanding and applying type guards effectively enhances the reliability and maintainability of your TypeScript applications.

Comments