Narrowing with typeof
Use the typeof operator to narrow a union to a specific primitive type.
Syntax
if (typeof x === "string") { }Type narrowing is how TypeScript figures out a more specific type inside a conditional. The typeof operator narrows unions of primitives.
After a check like if (typeof x === "string"), TypeScript knows x is a string in that branch and lets you use string methods safely.
Example
Loading editorβ¦
Press Run to execute the code.
When to use it
- A utility function accepts string | number and uses typeof to call toUpperCase() only on string inputs.
- A serialization helper checks typeof to stringify numbers differently from strings in a union type.
- A safe division function uses typeof to guard against non-number inputs before performing arithmetic.
More examples
typeof to narrow string | number
Narrows a string | number union using typeof so each branch accesses only the methods available on that specific type.
function formatValue(val: string | number): string {
if (typeof val === 'string') {
return val.toUpperCase();
}
return val.toFixed(2);
}
console.log(formatValue('hello')); // 'HELLO'
console.log(formatValue(3.14159)); // '3.14'Narrowing inside a loop
Applies typeof checks inside a forEach to safely handle each type in a mixed-type array.
const items: (string | number | boolean)[] = ['a', 1, true, 'b', 2];
items.forEach((item) => {
if (typeof item === 'string') console.log('str:', item.toUpperCase());
if (typeof item === 'number') console.log('num:', item * 10);
if (typeof item === 'boolean') console.log('bool:', !item);
});typeof for function overload simulation
Combines overload signatures with typeof narrowing in the implementation to handle each variant with the correct operation.
function double(x: string): string;
function double(x: number): number;
function double(x: string | number): string | number {
if (typeof x === 'string') return x + x;
return x * 2;
}
console.log(double('ha')); // 'haha'
console.log(double(5)); // 10
Discussion