Object access returns an "Object is possibly 'undefined'" error with type guard

I’m writing a function that checks if two strings are anagrams, I mapped their letters and the count of their occurrence inside an object with type Record<string, number | undefined>. But when I try to access a property it throws an Object is possibly 'undefined'" error even with type guard. I’m curious to know why typescript is throwing such error.

The function:

function validAnagram(string1: string, string2: string): boolean {
    if (string1.length !== string2.length) {
        return false;
    }

    const string1Map: Record<string, number | undefined> = {};

    // Map string1 letters and their occurrences
    for (let idx = 0; idx <= string1.length; idx += 1) {
        const key: string = string1[idx];
        string1Map[key] = (string1Map[key] ?? 0) + 1;
    }

    // Compare string2 to string1Map
    for (let idx = 0; idx <= string2.length; idx += 1) {
        const key: string = string2[idx];

        // Exit if letter is undefined or 0
        if (string1Map[key] === undefined || string1Map[key] === 0) {
            return false;
        }

        string1Map[key]! -= 1; // "Object is possibly 'undefined'" error
    }

    return true;
}

>Solution :

Yes, it’s a bit unfortunate that Typescript cannot deal with type guards that involve property access like this one. An easy way to fix it is to write the contents of your for loop like this:

        const letter = string1Map[key];
        // Exit if letter is undefined or 0
        if (letter === undefined || letter === 0) {
            return false;
        }

        string1Map[key] = letter - 1;

This way, Typescript can correctly narrow the type of letter as it is an independent variable.

Leave a Reply