What is TypeGuard in TypeScript
TypeGuard is a mechanism in TypeScript that helps narrow a variable's type within a code block. It allows TypeScript to precisely determine a variable's type based on conditions, making code safer and allowing the compiler to better check types.
TypeGuard is used to check a variable's type and narrow its type in a specific context. This is especially useful when a variable can be one of several types and you need to perform actions specific to a particular type.
TypeGuard Working Principle
TypeScript provides several ways to implement TypeGuard, including:
- Custom TypeGuard functions.
- Type checking operators like
typeofandinstanceof. - Custom type checks using
is.
TypeGuard Usage Examples
-
Example with typeof:
The
typeofoperator allows checking primitive types likestring,number,booleanand others. In the case of TypeGuard, this allows narrowing a variable's type in a code block.function printLength(value: string | number) { if (typeof value === "string") { console.log(value.length); // Works since value is definitely string } else { console.log(value.toFixed(2)); // Works since value is definitely number } } printLength("Hello"); // Output: 5 printLength(42); // Output: 42.00In this example, the typeof operator allows TypeScript to understand that in the if block the value variable is a string, and in the else block — a number.
-
Example with instanceof:
The
instanceofoperator is used to check object types, for example, classes. This allows precisely determining an object's type if it's an instance of some class.class Dog { bark() { console.log("Woof!"); } } class Cat { meow() { console.log("Meow!"); } } function speak(animal: Dog | Cat) { if (animal instanceof Dog) { animal.bark(); // Access to bark method since animal is Dog } else { animal.meow(); // Access to meow method since animal is Cat } } const dog = new Dog(); const cat = new Cat(); speak(dog); // Output: Woof! speak(cat); // Output: Meow! -
Custom TypeGuard functions
You can create your own functions for type checking and using TypeGuard with the
iskeyword.type Dog = { bark: () => void }; type Cat = { meow: () => void }; function isDog(animal: Dog | Cat): animal is Dog { return (animal as Dog).bark !== undefined; } function speak(animal: Dog | Cat) { if (isDog(animal)) { animal.bark(); // animal is now definitely type `Dog` } else { animal.meow(); // animal is now definitely type `Cat` } } const dog: Dog = { bark: () => console.log("Woof!") }; const cat: Cat = { meow: () => console.log("Meow!") }; speak(dog); // Output: Woof! speak(cat); // Output: Meow!
Why use TypeGuard?
-
Type safety: TypeGuard helps avoid errors related to incorrect variable usage, as TypeScript precisely understands which variable type is used in each code block.
-
Improved code readability: Using TypeGuard makes code more understandable and predictable, as it explicitly indicates which data types are processed in each block.
-
Better code understanding for IDE: TypeScript and IDEs (e.g., Visual Studio Code) can use TypeGuard to improve hints, autocomplete and refactoring, speeding up development and improving code work.