Using Map<> in Typescript with strictNullChecks Preference

Consider the following basic 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'
        }
    }

In addition, with strictNullChecks and strict enabled in tsconfig.json.

Even though we are checking for a key in subscribers with the current event, the TypeScript compiler raises an error suggesting that this.subscribers.get(event) could be undefined.

Is it possible for this.subscribers.get(event) to actually be undefined here?

How can we resolve or suppress this warning message?

Answer №1

The Map type explicitly mentions that the get function may return undefined:

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

This is why you are encountering an error when strictNullChecks is enabled.

To address this, you can utilize the non-null assertion operator to indicate to the compiler that you are certain it contains a value:

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

Alternatively (which I consider to be a better approach), you can refactor your code as follows:

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);
}

Answer №2

Have you ever considered creating a new interface or class that completely eliminates the possibility of undefined values?

interface StrictMap<K, V> {
    ...
    get(key: K): V /* `| undefined` -> main difference with standard `Map` interface: No undefined values allowed */;
    ...
}

PS: Interestingly enough, I was actually in search of such a concept when I stumbled upon this Stack Overflow post ;)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Error: monaco has not been declared

My goal is to integrate the Microsoft Monaco editor with Angular 2. The approach I am taking involves checking for the presence of monaco before initializing it and creating an editor using monaco.editor.create(). However, despite loading the editor.main.j ...

What causes the "Unknown provider: defaultFilterProvider <- defaultFilter" error in AngularJS when using angular-filters?

After incorporating angular-filters into my application.js, I am encountering the following error: Unknown provider: defaultFilterProvider <- defaultFilter Can someone advise on how to resolve this issue? ...

Steps for resolving the issue "Error: Module not found 'C:Users odri odejs_paypalsrcindex.js'" in Node.js

As I attempt to launch my Node.js project, I'm running into a module resolution error that reads as follows: PS C:\Users\rodri\nodejs_paypal> npm run dev <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail=" ...

React Native's SQLite storage library does not seem to be providing any response

Currently, I am utilizing the SQLite database through react-native-sqlite-storage. However, when attempting to display the result in an alert, it shows as undefined. I have also attempted performing the operation without using await and async. MainFil ...

Determining if there is a common element in two arrays to yield a true outcome

In my Ionic app built with Angular 1.x, I am dealing with two arrays containing numbers: var arr1 = [1,32,423,43,23,64,232,5,67,54]; var arr2 = [11,32,1423,143,123,64,2232,35,467,594]; The common numbers in these arrays are 32 and 64. I need a JavaScript ...

Can you please provide information on the callback function type used in the filter method of TypeScript?

transactionsData = [ { id: 101, name: 'transaction 1' }, { id: 201, name: 'transaction 2' }, { id: 301, name: 'transaction 3' }, { id: 401, name: 'transaction 4' } ]; constructor( private objGreetingsSe ...

Retrieve the content from a textarea and insert it into a different textarea with additional text included

Users can input HTML codes into a textarea named txtar1. A 'generate' button is available; Upon clicking the 'generate' button, the content of txtar1 will be transfered to another textarea named txtar2 with additional CSS code. Here&ap ...

Issue with ui-sref functionality in Ionicview, functioning properly on browser, device, and emulator

My development process involves using ionic to create an application. While most of the links work without any issues, I have encountered a specific problem with one list in ionicview. The HTML code for this particular list is as follows: <ion-list ...

Utilizing Vue 3 with TypeScript for enforcing type checking on single file components' props

In my exploration of Vuetify and other sources, I discovered that it is possible to incorporate type checking for props within the template tag. Let's consider a simple button component: <template> <div> <button>{{ label ...

Run a Javascript function two seconds after initiating

My goal is to implement a delay in JavaScript using either setInterval or setTimeout, but I am facing an issue where the primary element is getting removed. Code that works fine without Javascript delay: const selectAllWithAttributeAdStatus = document. ...

Obtain latitude and longitude coordinates for the corners of a React Leaflet map

Currently, I am working with react-leaflet and facing a particular challenge: In my map application, I need to display pointers (latitude, longitude) from the database. However, retrieving all these pointers in one call could potentially cause issues due ...

Tips for creating a breakpoint in Sass specifically for a 414px iPhone screen size

For my latest project, I am utilizing sass and looking to incorporate a sass breakpoint or media query. My goal is to have the code execute only if the screen size is 414px or less. Below is my existing code: @include media-breakpoint-down(sm) { .sub-men ...

Here is a unique version of the text: "Adding an Ajax variable from a loop to a <a href='' ></a> tag: A Simple Guide"

Hello all, I am new to Ajax and I am using it to retrieve values from my database in the form of an object array from a separate PHP file. I am then displaying them in a table, which is working fine. However, I want to create a link and append the ID obtai ...

What is the best way to incorporate an "if" statement into my code?

I'm in the process of setting up a section on my website where users can get live price estimates based on a value they input. While I have most of the formula in place, there's one final element that I need to figure out: introducing a minimum f ...

Instructions for implementing onclick functionality on an iframe element

Is it possible to use the onclick event in an iframe tag to call a JavaScript function? I have integrated a Facebook like button on my website using an iframe code. When a user clicks on the like button, I would like them to be redirected to a 'thank ...

Calculating the position of a parallax background within a window

Seeking assistance with what initially seemed like a straightforward task, but has now become quite puzzling. I'm currently working on a basic jQuery script that binds to the window scroll function. Despite seemingly having all the necessary variable ...

Only the initial AJAX request is successful, while subsequent requests fail to execute

I am facing an issue with multiple inputs, each requiring a separate AJAX request. < script type = "text/javascript" > $(document).ready(function() { $("#id_1").change(function() { var rating1 = $(this).v ...

How should the directory be organized for the param with a prefix in Nuxt.js?

My route is set up as /en/rent-:productSlug How should I organize the directory for this route, considering that the parameter productSlug includes the prefix rent? ...

Display and verify the real value of JavaScript constructor

Currently, I am examining a Javascript datatable constructor function that involves handling checkbox elements. A variable named field is passed with all the values for the checkbox element, which are then broken down into separate variables for each elem ...

What does an exclamation mark signify in Angular / Type Script?

Being a newcomer in the world of front end development, I am currently teaching myself Angular (11.2.10). While exploring a sample project, I noticed this particular piece of html template code written by another person and utilized in multiple places: < ...