How to use Type Guards in TypeScript ?
Here are the methods to use type guards in TypeScript:
1. Using typeof Type Guards
The typeof operator checks the type of a variable, primarily for primitive types like string, number, boolean, etc.
function processValue(value: string | number) {
if (typeof value === 'string') {
console.log(value.toUpperCase());
} else {
console.log(value.toFixed(2));
}
}
processValue('Hello');
processValue(123.456);
- If value is a string, toUpperCase() is called.
- If value is a number, toFixed(2) is called.
Output:
HELLO
123.46
2. Using instanceof Type Guards
The instanceof operator checks if an object is an instance of a specific class or constructor function.
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();
}
}
const myDog = new Dog();
const myCat = new Cat();
makeSound(myDog);
makeSound(myCat);
- If animal is an instance of Dog, bark() is called.
- If animal is an instance of Cat, meow() is called.
Output:
Woof!
Meow!
3. Using the 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();
}
}
const pigeon: Bird = { fly: () => console.log('Flying') };
const salmon: Fish = { swim: () => console.log('Swimming') };
move(pigeon);
move(salmon);
- If animal has a fly method, it's a Bird, and fly() is called.
- If animal has a swim method, it's a Fish, and swim() is called.
Output:
Flying
Swimming
4. Using User-Defined Type Guards
Custom type guard functions use type predicates to narrow down types.
interface Car {
drive: () => void;
}
interface Boat {
sail: () => void;
}
function isCar(vehicle: Car | Boat): vehicle is Car {
return (vehicle as Car).drive !== undefined;
}
function operate(vehicle: Car | Boat) {
if (isCar(vehicle)) {
vehicle.drive();
} else {
vehicle.sail();
}
}
const sedan: Car = { drive: () => console.log('Driving') };
const yacht: Boat = { sail: () => console.log('Sailing') };
operate(sedan);
operate(yacht);
- The isCar function checks if vehicle has a drive method.
- In operate, isCar determines whether to call drive() or sail().
Output:
Driving
Sailing
Type Guards in TypeScript - FAQs
How do you use typeof in Type Guards?
Use the typeof operator to check primitive types like string, number, or boolean within a conditional block.
What is the purpose of instanceof in Type Guards?
The instanceof operator is used to check if an object is an instance of a specific class, enabling access to class-specific properties and methods.
How do you implement custom Type Guards?
Custom Type Guards use type predicates (e.g., value is Type) to define functions that narrow down types based on runtime checks.
Can you use the in operator in Type Guards?
Yes, the in operator checks for the existence of a property in an object, useful for differentiating between object types in union types.
Why are Type Guards necessary for union types?
Yes, Type Guards can be used with interfaces, especially through custom Type Guards that check for specific properties.