What is the meaning of "type guards" in TypeScript

  • In TypeScript, "type guards" are a way to narrow down the type of a variable within a conditional block of code. They are used to perform runtime checks on values and refine their types accordingly, providing more precise type information to the TypeScript compiler.
  • Type guards are particularly useful when working with union types or when TypeScript's type inference isn't sufficient to determine the specific type of a variable. They allow you to check the type of a variable at runtime and perform different operations or access specific properties based on that type.
TypeScript provides several mechanisms for implementing type guards:
  • typeof type guards: By using the `typeof` operator followed by a type, you can check the type of a primitive value, such as strings, numbers, booleans, or symbols. For example:

    function printLength(value: string | number) {
        if (typeof value === 'string') {
            console.log(value.length);
        } else {
            console.log('Invalid type');
        }
    }

  • instanceof type guards: The `instanceof` operator allows you to check if an object is an instance of a specific class or constructor function. This is useful when dealing with inheritance and class hierarchies. For example:

    class Circle {
        radius: number;
        constructor(radius: number) {
            this.radius = radius;
        }
    }

    class Square {
        sideLength: number;
        constructor(sideLength: number) {
            this.sideLength = sideLength;
        }
    }

    function calculateArea(shape: Circle | Square) {
        if (shape instanceof Circle) {
            console.log(Math.PI * shape.radius ** 2);
        } else if (shape instanceof Square) {
            console.log(shape.sideLength ** 2);
        } else {
            console.log('Invalid shape');
        }
    }

  • user-defined type guards: You can create your own functions to serve as type guards. A user-defined type guard is a function that returns a type predicate, indicating whether a value satisfies a specific type. The return type of a type guard is a type predicate, which is a type assertion with `value is Type` syntax. For example:

    interface Cat {
        name: string;
        meow(): void;
    }

    interface Dog {
        name: string;
        bark(): void;
    }

    function isCat(animal: Cat | Dog): animal is Cat {
        return 'meow' in animal;
    }

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

  • Type guards help TypeScript infer and narrow down types, enabling more precise type checking and better autocompletion in code editors. They are an essential feature for working with complex type systems and ensuring type safety in TypeScript programs.

No comments:

Post a Comment