Type narrowing in TypeScript refers to the process of narrowing down the type of a variable within a certain block of code based on certain conditions. This is often used with union types or type guards to refine the type of a variable and enable more precise type checking. Here are some common techniques for type narrowing in TypeScript:
Type Guards:
Use functions or conditions that act as type guards to narrow down the type. For example, the typeof
operator can be used to check the type of a variable.
typescriptfunction isNumber(value: string | number): value is number {
return typeof value === 'number';
}
let x: string | number = 42;
if (isNumber(x)) {
// Inside this block, TypeScript knows that x is of type number
console.log(x.toFixed(2));
}
Instanceof:
The instanceof
operator can be used to check if an object is an instance of a particular class.
typescriptclass Animal {
move() {
console.log("Moving...");
}
}
class Bird extends Animal {
fly() {
console.log("Flying...");
}
}
function moveAnimal(animal: Animal) {
if (animal instanceof Bird) {
// Inside this block, TypeScript knows that animal is of type Bird
animal.fly();
} else {
animal.move();
}
}
Custom Type Guards: You can create custom functions that act as type guards.
typescriptinterface Square {
kind: "square";
size: number;
}
interface Circle {
kind: "circle";
radius: number;
}
type Shape = Square | Circle;
function isSquare(shape: Shape): shape is Square {
return shape.kind === "square";
}
function area(shape: Shape): number {
if (isSquare(shape)) {
// Inside this block, TypeScript knows that shape is of type Square
return shape.size * shape.size;
} else {
// Inside this block, TypeScript knows that shape is of type Circle
return Math.PI * shape.radius ** 2;
}
}
Nullish Coalescing (??
):
The nullish coalescing operator ??
can be used to narrow down types based on non-nullish values.
typescriptfunction printLength(value?: string | null) {
// Using nullish coalescing to check for non-nullish values
const length = value ?? "N/A";
console.log(length.length); // TypeScript knows that length is a number here
}
These are just a few examples of type narrowing techniques in TypeScript. By using these techniques, you can make your code more type-safe and take advantage of TypeScript's static type checking.