What Are Type Guards?
Type Guards are TypeScript constructs that allow you to refine or narrow down the type of a value within a certain code block. They are especially useful when dealing with union types or unknown values.
The typeof
The simplest Type Guard in TypeScript is the typeof
check. You've likely used it to differentiate between primitive types.
function logValue(value: string | number) {
if (typeof value === 'string') {
console.log('This is a string:', value);
} else {
console.log('This is a number:', value);
}
}
The instanceof
When working with classes and inheritance, instanceof
is your go-to Type Guard.
class Animal {
move() {
console.log('Moving... 🚶‍♂️');
}
}
class Bird extends Animal {
fly() {
console.log('Flying... 🦅');
}
}
function moveAnimal(animal: Animal) {
if (animal instanceof Bird) {
animal.fly();
} else {
animal.move();
}
}
Type Guards and Unions
Unions are a common source of type-related issues. Type Guards can help ensure that your code handles union types gracefully.
type Result = { success: true; value: number } | { success: false; error: string };
function processResult(result: Result) {
if (result.success) {
console.log('Value is', result.value);
} else {
console.error('Error:', result.error);
}
}
With Custom Properties
The in
operator is handy when dealing with objects that might have specific properties.
interface Car {
brand: string;
speed: number;
}
function isFast(car: Car | { name: string }): car is Car {
return 'speed' in car;
}
With typeof
and instanceof
Type Guards can be combined to handle complex situations effectively.
function processInput(input: string | number | Animal) {
if (input instanceof Animal) {
input.move();
} else if (typeof input === 'string') {
console.log('You entered a string:', input.toUpperCase());
} else {
console.log('You entered a number:', input.toFixed(2));
}
}
Top comments (0)