Open In App

TypeScript Equality Narrowing Type

Last Updated : 25 Oct, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we are going to learn about Equality narrowing Type in Typescript. TypeScript is a popular programming language used for building scalable and robust applications. In TypeScript, “equality narrowing” refers to the process of narrowing the type of a variable based on equality checks or comparisons. TypeScript can use equality checks like ===, ==, !==, !=, or comparisons like <, >, <=, >= to infer more specific types. It can also use switch statements.

JavaScript’s looser equality checks with == and != also get narrowed correctly. If you’re unfamiliar, checking whether something == null actually not only checks whether it is specifically the value null – it also checks whether it’s potentially undefined. The same applies to == undefined: it checks whether a value is either null or undefined.

Example 1: In this example, We have a processValue function that takes a parameter value of type number | string. Inside the function, we use “typeof” value === ‘number’ to check if the value is of type ‘number’. If it is, TypeScript narrows the type of value to ‘number’ within the if block., it’s safe to perform numerical operations on value. In the else block, TypeScript narrows the type of value to ‘string’ because it knows that it can’t be a number (due to the check-in of the if block), and it allows you to call toUpperCase() on it.

 

Javascript




function processValue(value: number | string): void {
    if (typeof value === 'number') {
        // Inside this block, TypeScript
        // narrows the type of value to 'number'
        // It knows value is a number
        console.log(value + 10);
    } else {
        // Inside this block, TypeScript
        // narrows the type of value to 'string'
        // It knows that the value is a string
        console.log(value.toUpperCase());
    }
}
  
// Example usage:
processValue(5);
processValue('GeeksforGeeks');


Output:

z81

Example 2: In this example,We have a processArray function that accepts an argument arr of type number[] or string[], indicating it can work with arrays of numbers or strings.Inside the function, we use Array.isArray(arr) to check if arr is an array. If it is, TypeScript narrows the type of arr to either number[] or string[] within the if block.Within the forEach loop, TypeScript further narrows the type of item based on the type of elements in the array. If item is a number, it knows it’s a number; if it’s a string, it knows it’s a string.This allows us to safely perform operations specific to numbers or strings within the loop without TypeScript raising type errors. When we call processArray with numberArray and stringArray, TypeScript correctly narrows the types and performs type-safe operations within the function.

Javascript




function processArray(arr: number[] | string[]): void {
    if (Array.isArray(arr)) {
        // TypeScript narrows the type of arr to 
        // 'number[]' or 'string[]' inside this block
        arr.forEach((item) => {
            if (typeof item === "number") {
                // TypeScript narrows the 
                // type of item to 'number' here
                console.log(`Number: ${item}`);
            } else {
                // TypeScript narrows the 
                // type of item to 'string' here
                console.log(`String: ${item}`);
            }
        });
    }
}
  
const numberArray: number[] = [1, 2, 3];
const stringArray: string[] = ["Typescript", "Java", "React"];
  
processArray(numberArray);
processArray(stringArray);


Output:

z82

Example 3: In this example, The printPersonInfo function takes an argument person, which is of type Person. A person is an interface with a name property and an optional age property. Inside the function, we use the in operator to check whether the age property exists in the person object. If the age property exists (‘age’ in person evaluates to true), TypeScript narrows the type of person inside the if block to include the age property. We can then safely assess ‘person.age’. If the age property does not exist (‘age’ in person evaluates to false), TypeScript narrows the type inside the else block to exclude the age property.

Javascript




interface Person {
    name: string;
    age?: number;
}
  
function printPersonInfo(person: Person) {
    if ('age' in person) {
        // Inside this block, 'person' is 
        // narrowed to include the 'age' property
        console.log(`Name: ${person.name},
         Age: ${person.age}`);
    } else {
        // Inside this block, 'person' is 
        // narrowed to exclude the 'age' property
        console.log(`Name: ${person.name},
         Age not provided`);
    }
}
  
const GeeksforGeeks: Person = { 
    name: 'GeeksforGeeks', age: 30 };
const Geek: Person = { name: 'Geek' };
  
printPersonInfo(GeeksforGeeks);
printPersonInfo(Geek);


Output:

z85



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads