Welcome back! I am Mihir, and in this lesson we will learn typeof narrowing in TypeScript.
typeof is one of the simplest ways to narrow primitive union types.
Basic typeof Narrowing
function format(value: string | number) {
if (typeof value === "string") {
return value.toUpperCase();
}
return value.toFixed(2);
}Inside the first block, value is a string.
After that block, value is a number.
typeof with Boolean
function describe(value: string | boolean) {
if (typeof value === "boolean") {
return value ? "Yes" : "No";
}
return value.trim();
}TypeScript narrows value based on the result of typeof.
typeof with undefined
function greet(name?: string) {
if (typeof name === "undefined") {
return "Hello, guest";
}
return `Hello, ${name.toUpperCase()}`;
}After checking for undefined, TypeScript knows name is a string.
typeof with Functions
function run(value: string | (() => string)) {
if (typeof value === "function") {
return value();
}
return value;
}typeof value === "function" narrows the value to a callable function.
typeof Results
Common typeof results include:
"string""number""boolean""undefined""function""object""symbol""bigint"
These strings are what TypeScript uses for narrowing.
Be Careful with null
In JavaScript:
typeof null;The result is:
"object"So this check is not enough:
function printName(user: { name: string } | null) {
if (typeof user === "object") {
console.log(user.name);
}
}user could still be null.
Better:
function printName(user: { name: string } | null) {
if (user !== null) {
console.log(user.name);
}
}typeof Does Not Check Object Shapes
type User = {
name: string;
};
function print(value: User | string) {
if (typeof value === "object") {
console.log(value.name);
}
}This works for this simple union, but typeof only tells you that the value is an object. It does not verify every property.
For object shapes, other narrowing techniques are often better.
Quick Recap
typeofis great for primitive narrowing.- It works with strings, numbers, booleans, undefined, functions, symbols, and bigint.
- Be careful because
typeof nullis"object". typeofdoes not deeply validate object structure.
Next up, we will learn Truthiness Narrowing →.