typeof
operator. TypeScript’s typeof
operator can be used to get the type of a variable at compile - time, and it can be leveraged to narrow down the possible types of a variable, enabling more precise type checking and better code safety. This blog will explore the fundamental concepts, usage methods, common practices, and best practices of using typeof
for type narrowing in TypeScript.Type narrowing is the process of taking a wider type and making it more specific. For example, if you have a variable that can be either a string
or a number
, type narrowing can help you determine whether it is a string
or a number
at a certain point in the code, so that you can perform operations specific to that type.
typeof
Operator in TypeScriptIn JavaScript, the typeof
operator returns a string indicating the type of a value. In TypeScript, the typeof
operator can also be used in type positions to refer to the type of a variable. When used in conditional statements, it can be used to narrow down the type of a variable.
Here are the possible return values of the typeof
operator in JavaScript (and TypeScript):
"undefined"
"boolean"
"number"
"string"
"object"
"function"
"symbol"
typeof
in if
StatementsThe most common way to use typeof
for type narrowing is in if
statements. Consider the following example:
function printValue(value: string | number) {
if (typeof value === 'string') {
// Inside this block, TypeScript knows that 'value' is a string
console.log(value.toUpperCase());
} else {
// Here, TypeScript knows that 'value' is a number
console.log(value.toFixed(2));
}
}
printValue('hello');
printValue(3.14159);
In this example, the typeof
operator is used in the if
statement to check if value
is a string
. If the condition is true
, TypeScript narrows down the type of value
to string
inside the if
block. Otherwise, it narrows the type to number
in the else
block.
typeof
with switch
StatementsYou can also use typeof
in switch
statements for type narrowing. Here is an example:
function handleValue(value: string | number | boolean) {
switch (typeof value) {
case 'string':
console.log(`The string is: ${value}`);
break;
case 'number':
console.log(`The number is: ${value}`);
break;
case 'boolean':
console.log(`The boolean is: ${value}`);
break;
default:
console.log('Unexpected type');
}
}
handleValue('test');
handleValue(42);
handleValue(true);
When writing functions that accept union types as parameters, using typeof
for type narrowing can make the function more robust. For example, a function that can accept either a string or an array of strings and returns the length:
function getLength(value: string | string[]) {
if (typeof value === 'string') {
return value.length;
} else {
return value.reduce((acc, str) => acc + str.length, 0);
}
}
console.log(getLength('hello'));
console.log(getLength(['hello', 'world']));
Type narrowing can also be useful in error handling scenarios. For example, when a function can return either a result or an error object:
type Result = { success: true; data: string } | { success: false; error: string };
function processResult(result: Result) {
if (typeof result.error === 'string') {
console.error(`Error: ${result.error}`);
} else {
console.log(`Data: ${result.data}`);
}
}
const successResult: Result = { success: true, data: 'Some data' };
const errorResult: Result = { success: false, error: 'Something went wrong' };
processResult(successResult);
processResult(errorResult);
When using typeof
for type narrowing, try to keep the conditions simple. Complex conditions can make the code harder to read and maintain. For example, avoid nested typeof
checks if possible.
If you can determine the type of a variable early in a function and return from the function, it can make the code more readable. Consider the following example:
function processValue(value: string | number) {
if (typeof value === 'string') {
return value.toUpperCase();
}
return value.toFixed(2);
}
console.log(processValue('example'));
console.log(processValue(5.67));
When using typeof
for type narrowing in more complex scenarios, it can be helpful to add comments to the code to explain the type narrowing logic. This makes the code more understandable for other developers.
TypeScript’s typeof
operator is a valuable tool for type narrowing. It allows you to write more precise and safer code by refining the type of a variable within a certain scope. By using typeof
in if
statements, switch
statements, and other conditional constructs, you can perform operations specific to the narrowed type. Following the common practices and best practices outlined in this blog can help you use typeof
for type narrowing effectively.