TypeScript Type Guards & Narrowing
Type Narrowing
// typeof narrowing
function padLeft(value: string, padding: string | number) {
if (typeof padding === 'number') {
return ' '.repeat(padding) + value;
}
return padding + value;
}
// Truthiness narrowing
function printAll(strs: string | string[] | null) {
if (strs && typeof strs === 'object') {
// TypeScript knows strs is string[]
for (const s of strs) {
console.log(s);
}
} else if (typeof strs === 'string') {
console.log(strs);
}
}
// Equality narrowing
function example(x: string | number, y: string | boolean) {
if (x === y) {
// x and y must both be string
x.toUpperCase();
y.toUpperCase();
}
}
// in operator narrowing
type Fish = { swim: () => void };
type Bird = { fly: () => void };
function move(animal: Fish | Bird) {
if ('swim' in animal) {
animal.swim();
} else {
animal.fly();
}
}
// instanceof narrowing
function logValue(value: Date | string) {
if (value instanceof Date) {
console.log(value.toUTCString());
} else {
console.log(value.toUpperCase());
}
}Keep your own version of these notes — editable, searchable, and organised by your stack.
Start free