Typescript - Inline check for undefined not properly functioning (Potential 'undefined' object detected.ts(2532))

I encountered an issue with TypeScript:

const myFunction = (
  param1: string | undefined,
  param2: { someProp: string } | undefined
) => {
  if (!param1 && !param2) {
    return;
  }

  // I am facing this Typescript error here:
  //  (parameter) param2: { someProp: string } | undefined
  //  Object is possibly 'undefined'.ts(2532)
  const param3 = param1 ? param1 : param2.someProp;
};

The following approach works, but it seems redundant to handle null or undefined twice:

const param4 = param1 ? param1 : param2 ? param2.someProp : null;

I would like to mention that the strictNullChecks option is enabled in the compilerOptions and I prefer to keep it that way.

Any insights on why this error occurs?

You can find the code in this CodeSandbox: https://codesandbox.io/s/jn2mp01q2v

Answer ā„–1

The unfortunate reality when it comes to the TypeScript compiler is that it doesn't quite match up to human intelligence (at least not in TypeScript 3.4). This means that its control flow analysis falls short compared to what a human can do. While the compiler is consistent in its analysis, my own analytical skills tend to falter when I'm hungry.

If you perform a check on a variable with a union type and eliminate one or more of the options within that union, the compiler will appropriately narrow down the type of the variable:

param1.charAt(0); // error, possibly undefined
if (!param1) return;
param1.charAt(0); // now okay

However, one limitation of the compiler is that it does not track correlated variables outside of discriminated unions. By checking for

if (!param1 && !param2) return;

You are removing the possibility of both param1 and param2 being

undefined</code simultaneously, linking these formerly independent variables. The compiler does not recognize this correlation, treating them as independent entities, causing your issue to persist.</p>

<p>As suggested in another answer, you could utilize a <a href="https://www.typescriptlang.org/docs/handbook/basic-types.html#type-assertions" rel="noreferrer">type assertion</a> if you believe you have a better understanding than the compiler:</p>

<pre><code>const param3 = param1 ? param1 : param2!.someProp; // Showing superiority over the compiler šŸ¤“

I've used the non-null assertion operator ! to assert dominance over the machine. Keep in mind that such assertions carry risks, so ensure there's no chance of param2 being

undefined</code before proceeding.</p>

<hr>

<p>An alternative approach is restructuring your code to guide the compiler through a feasible analysis:</p>

<pre><code>const param3 = param1 || (param2 ? param2.someProp : undefined);
if (!param3) return;
param3.charAt(0); // string

This method streamlines the process while ensuring each parameter is only checked once. The variable param3 is of type string | undefined, only becoming

undefined</code if both <code>param1
and param2 are falsy. It eliminates union constituents for each variable step by step without confusing the compiler with correlated types.

Either solution should address your needs. Best of luck! hope this proves helpful.

Answer ā„–2

The reason for the issue is that param2 has been assigned two different types, one being an object and the other undefined. To resolve this problem, you need to update the code as follows:

const param3 = param1 ? param1 : (param2 as any).someProp;

By making this change, the code should work correctly.

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

Choose an option from a list of items in a nested array by

I'm working with a nested array (3d) and I want to populate a drop-down select menu with its values using PHP and jQuery I've tried implementing this for two-level arrays like categories and sub-categories, but what if some sub-categories have f ...

Error encountered when asynchronously iterating over an object in TypeScript

Could someone please help me understand why I am getting an error with this code? var promise = new Promise((resolve, reject) => { resolve([1, 2, 3, 4, 5]); }); async function doSomethingAsync() { var data = await promise; data.forEach(v = ...

The Vue instance methods provide a way to access and manipulate formatted properties

I am looking to implement a method that will generate the appropriate email format to be used as the href value in an anchor tag. This method should return the formatted string in the following format: "mailto:[email protected]". var facultyInformat ...

What could be the reason my hex code generator is outputting variable names instead of their assigned values?

I am currently working on developing a unique hex code generator using random values. At the moment, my focus is on displaying six random values in the HTML. // The characters A-F and numbers 0-9 can be utilized var button = document.querySelector(&quo ...

Create a React MUI component that allows menu items to become sticky when selected

Is there a way to make the mui MenuItem stay sticky to Select while scrolling down? To see the issue in action, check out this codesandbox example https://codesandbox.io/s/quirky-knuth-5hr2dg?file=/Demo.tsx Simply click on the select and start scrolling ...

dynamically assigning a style attribute based on the dimensions of an image retrieved from a URL

My aim is to determine whether or not I should use an image based on its dimensions. To achieve this, I came across a function on stack overflow that can retrieve the dimensions of an image just by using its URL. Here is the code snippet they provided: f ...

Exploring the synergies between Angular Dragula and utilizing the $index property

Currently, I have implemented an ng-repeat of rows that can be rearranged using Angular Dragula. Despite successful drag-and-drop functionality, the $index in ng-repeat remains constant for each item even after reordering. The screenshot below depicts the ...

Tips on showcasing a nested array in Next.js or converting it into an object

{ "count": 2, "rows": [ { "id": "5ab46e31-391c-46a7-8e45-db9ada07626d", "name": "admin", "email": "<a href="/cdn-cgi/l/email-p ...

Utilize JSX to dynamically insert HTML tags onto a webpage

I am trying to achieve a specific task in JSX, where I want to identify all strings enclosed within delimiters :; and wrap them with HTML Mark tags to highlight them. However, the current implementation is not rendering the tags as expected. Is there a sol ...

How can I retrieve the Azure subscription IDs of the currently logged in user using @azure/msal-angular?

I successfully authenticated a user using @azure/msal-angular and received the id_Token, access_Token and tenant Id. Now I am looking to retrieve the logged in user's azure subscriptions. Is there a way to achieve this through msal or are there any Ja ...

On the second attempt to call setState within the componentDidMount method, it is not functioning as expected

As a newcomer, I am delving into the creation of a memory game. The main objective is to fetch data from an API and filter it to only include items with image links. On level one of the game, the task is to display three random images from the fetched data ...

Managing two simultaneous web service calls in Angular 2

Dealing with two parallel web service calls can be tricky. Sometimes the first call goes through first, and other times it's the second one. The problem arises when the function in my second service requires data from the first service call. I attemp ...

Scrolling vertically at regular intervals of 5 seconds

I am experimenting with creating a vertical scrolling animation. Within a div, I have 9 elements with overflow hidden, allowing only 3 elements to be visible at once. Every 5 seconds, I aim to add styles to the elements using negative margin-top values a ...

What is the best way to transfer weather data from a server to an HTML text area box?

Recently, I delved into the world of expressJS to set up a local server (localhost:3000). With the power of JavaScript (specifically in a file named app.js), I was able to send simple messages like "Hello World" to the browser. However, now I find myself f ...

User events in the fullCalendar

I'm feeling stuck. I currently have a basic fullCalendar setup for the User model in Rails. I want to add 2 buttons, allowing the User to separate the calendar into two views. One view would display only their own events, while the other would show al ...

Tips on sending filter parameters from AngularJS to Spring RestController using @MatrixVariable

Iā€™m struggling to figure out how to use $http.get in AngularJS to pass filter parameters. The URL is: http://localhost:8080/template/users/query;username=abcd;firstName=ding... The RestController looks like this: @RequestMapping(value={"/users/{query ...

Tips for dynamically changing the object based on the value type in JavaScript

How can I transform a nested object into a new object using JavaScript? I have an object obj where if the details property is an array, I want to use the first value of the array as the value in JavaScript. function transformObject(obj) { let map = {}; ...

The issue arises when the logout component fails to render even after the user has been authenticated. This problem resembles the one discussed in the React Router

While attempting to run the react-router docs example on the browser, I encountered an issue with the AuthButton component. The problem arises when the isAuthenticated value changes to true but the signOut button fails to display. import React from ' ...

The issue with updating values in the jQuery UI datepicker persists

When using the jquery datepicker ui, you may notice that the value attributes of the associated html fields do not update immediately. For example: http://jsfiddle.net/4tXP4/ Check out this link for more details: http://jqueryui.com/demos/datepicker/al ...

Ways to streamline the type from typeof T down to T

One important aspect of my function is its signature, which looks like the following. waitMessage<T extends IIPCMessagesConstructors>(wantedMessageType: T): Promise<// ?? //> The definition of IIPCMessagesConstructors is crucial and consists ...