Whenever you need to work or perform operations on function parameter variables with a union type, you need to narrow down or simplify the type from the union type you need to perform the operation on. This is process is called Narrowing in TypeScript.
TL;DR
// A simple function that adds 100 to the number
// we provided as an argument to the function
function add100ToNumber(num: string | number) {
// Narrowing Types:
// check if "num" parameter value is of type "number"
if (typeof num === "number") {
return num + 100;
} else {
// then check if "num" parameter value is of type "string"
// then convert string to number type
return Number(num) + 100;
}
}
// call the function with
// both the string and number values
// and both will be valid since we have
// added checks for both the types inside
add100ToNumber("100"); // ✅ valid. returns: 200
add100ToNumber(200); // ✅ also valid. returns: 300
For example, let's say we have a function called add100ToNumber()
with a parameter called num
which has a union type composed of both the string
and the number
type.
When calling the function, we have to add 100
to the number we provided to the function as an argument. It may be a string or number.
It can be done like this,
// function that adds 100 to the number
// we provided as an argument to the function
function add100ToNumber(num: string | number) {
return num + 100;
}
Now you may think this would work fine. But in the TypeScript world, this would be an error saying Operator '+' cannot be applied to types 'string | number' and 'number'.
.
What the error is saying is that you cannot directly add the number 100
to the function parameter num
which has a union type composed of both the string
and number
types. At this point, the TypeScript compiler is confused about which type to use. We have a string
type and a number
type to deal with.
// function that adds 100 to the number
// we provided as an argument to the function
function add100ToNumber(num: string | number) {
return num + 100; // 🔴 Error. Operator '+' cannot be applied to types 'string | number' and 'number'.
}
So to remove the error we have to Narrow types
in TypeScript. What it means is that we have to check to see if the parameter num
type is a string
or number
type and then do the appropriate operations on it.
First let's check to see if the num
parameter value is of number
type. To do that we can use an if conditional
statement and check the type using the typeof
operator like this,
// function that adds 100 to the number
// we provided as an argument to the function
function add100ToNumber(num: string | number) {
// Narrowing Types:
// check if "num" parameter value is of type "number"
if (typeof num === "number") {
return num + 100;
}
}
Inside the if
block we add the number 100
to the num
parameter and return it.
After checking for the number
type, now we have to check for the case when the num
parameter value is a string
type. If it is a string
type value then we would have to convert the string
to a number
type to do the addition with the number 100
.
It can be done like this,
// function that adds 100 to the number
// we provided as an argument to the function
function add100ToNumber(num: string | number) {
// Narrowing Types:
// check if "num" parameter value is of type "number"
if (typeof num === "number") {
return num + 100;
} else {
// then check if "num" parameter value is of type "string"
// then convert string to number type
return Number(num) + 100;
}
}
// call the function with
// both the string and number values
// and both will be valid since we have
// added checks for both the types inside
add100ToNumber("100"); // ✅ valid. returns: 200
add100ToNumber(200); // ✅ also valid. returns: 300
Now we have successfully removed the errors and added correct checks for every type in the num
parameter in the add100ToNumber
function. 🎉
See the above code live in codesandbox.
That's all 😃!