Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript: Usage of Map<> with strictNullChecks

Given the following simple class:

class Observer {
        private subscribers: Map<string, Array<((data: any) => void)>> = new Map();     

        public subscribe(event: string, callback: (data: any) => void) {
            if (!this.subscribers.has(event)) {
                this.subscribers.set(event, []);
            }

            this.subscribers.get(event).push(callback); //tsc says: Object is possibly 'undefined'
        }
    }

Furthermore, in tsconfig.json, the flags strictNullChecks and strict are enabled.

Although subscribers is checked for a key of the current event, the typescript compiler complains with the error message shown above (this.subscribers.get(event) is possibly undefined).

If I'm not completely wrong, this.subscribers.get(event) can never be undefined in this case.

How can I get rid of that message?

like image 745
tklepzig Avatar asked Nov 19 '17 11:11

tklepzig


People also ask

What is strictnullchecks in typescript?

Null pointers are one of the most common categories of bugs, yet they can be avoided to a large degree with the strictNullChecks TypeScript compiler flag. Since the strictNullChecks flag was only added in TypeScript 2, its usage isn't that widespread yet.

How do I enable strict null checks in typescript?

To enable StrictNullChecks open tsconfg.sys and add "strictNullChecks": true under the compilerOptions. With this set to true, you’ll get a type error if you try to use null or undefined wherever Typescript expects a concrete type.

How does map function works in typescript?

TypeScript map | How does map function works in TypeScript? map function in TypeScript is used to get the new array from the existing calling array. By using the map function, we can perform any operation on the array elements and create a new array. This newly created array can be with or without the key-value pair.

How to map or filter an array in typescript?

We can map () and filter () arrays, but there are no such operations for typescript maps. for that solution: Convert the map into an array of [key, value] pairs. Map or filter the array.


1 Answers

Typing of Map explicitly states that get can result in undefined:

interface Map<K, V> {
    ...
    get(key: K): V | undefined;
    ...
}

That's why you're getting error with strictNullChecks enabled.

You can use non-null assertion operator to inform the compiler that you're sure that it actually has value:

this.subscribers.get(event)!.push(callback);

Another option (the better one in my opinion) is to refactor your code in following way:

public subscribe(event: string, callback: (data: any) => void) {
    let callbacks = this.subscribers.get(event);
    if (!callbacks) {
        callbacks = []
        this.subscribers.set(event, callbacks);
    }

    callbacks.push(callback);
}
like image 153
Aleksey L. Avatar answered Sep 28 '22 22:09

Aleksey L.