Version 4.6.4 of TypeScript is flagging the code as invalid

How can I fix this Typescript problem?

const userInformation: {
      email: string;
      id: string;
      _token: string;
      _tokenExpirationDate: string;
    } = JSON.parse(localStorage.getItem('userData'));

Console Error Message

Error: src/app/auth/authservice.ts:56:20 - error TS2345: Argument of type 'string | null' is not assignable to parameter of type 'string'.
Type 'null' is not assignable to type 'string'.

I included the // @ts-ignore but WebStorm keeps showing an error.

Answer №1

Let's overlook the fact that JSON.parse() has a call signature declaration that returns the unsafe any type. For now, let's assume that if JSON.parse() doesn't return null, it will be a value of your expected object type.


There is a possibility that

localStorage.getItem("userData")
could be null, and TypeScript considers it an error to call JSON.parse(null) because the purpose of JSON.parse() is usually to parse strings encoding JSON values. While parsing null isn't a runtime error in JavaScript, it's a type error according to TypeScript. Refer to What does "all legal JavaScript is legal TypeScript" mean? for further details.

To make it more type safe, ensure only a string is passed like this:

const retrievedValue = localStorage.getItem('userData');
const userData = retrievedValue ? JSON.parse(retrievedValue) as {
  email: string;
  id: string;
  _token: string;
  _tokenExpirationDate: string;
} : null;

This compiles without errors, and now userData holds the type {email: string ... } | null, reflecting the union with the null type indicating that userData can be either a valid object or null.


If you prefer expediency over safety, you can deceive the compiler about the local storage result and assert that it's not null using the non-null assertion operator (!):

const userData: {
  email: string;
  id: string;
  _token: string;
  _tokenExpirationDate: string;
} | null = JSON.parse(localStorage.getItem('userData')!);

Note that the | null was manually added since the compiler no longer sees that possibility.

Playground link to code

Answer №2

If you're looking for a simple solution to your problem, I suggest doing the following:

const userData: {
  email: string;
  id: string;
  _token: string;
  _tokenExpirationDate: string;
} = JSON.parse(localStorage.getItem('userData') ?? "null");

Take note that the nullish coalascing operator (??) requires typescript 3.7.


If you want the type to account for the possibility of being null (in case 'userData' does not exist in localStorage), using a union type with null would be appropriate:

const userData: {
  email: string;
  id: string;
  _token: string;
  _tokenExpirationDate: string;
} | null = JSON.parse(localStorage.getItem('userData') ?? "null");

At this stage, it might be beneficial to define the userData type as an interface:

interface UserData {
  email: string;
  id: string;
  _token: string;
  _tokenExpirationDate: string;
}

const userData: UserData | null = JSON.parse(localStorage.getItem('userData') ?? "null");

Answer №3

If there is no assigned value in the localstorage, we can simply assign an empty string directly

let userStoredData = JSON.parse(localStorage.getItem('userData') ?? '');

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

What is causing the unexpected behavior of deferred.resolve in the q manual?

I can't seem to grasp this concept and it might be a silly question. Let's analyze the code snippet below: function throwError() { throw Error("can't touch this."); } var def = q.defer(); def.promise.then( function() { co ...

Guide on handling asynchronous data return within a reducer

I'm struggling to properly handle the state when receiving data from the back-end of my application. This is the code I have: if (action.type === actionTypes.getList) { const id = action.payload.userId; Axios.post(`${apiUrl}/lists`, { ...

Website loses its css after printing

I'm having trouble printing a website with a simple layout featuring two columns, each containing tables. The website I want to print is located at the following link: . However, when I try to print it using the JavaScript function window.print(), the ...

how can I enable pass-through functionality in express middleware?

Currently, I have a POST API endpoint named /users which is used to retrieve the list of users. The reason behind using POST instead of GET is because the request body can be quite large and it may not fit in the URL for a GET request. In this scenario, i ...

Cascading MVC 2 Dropdown menus

I am trying to bind a dropdown based on the change of another dropdown, but I keep getting an "Undefined" error. Here is my code snippet: <select id="BreakOutValue" class="input1_drop" onchange="onChange()" ></select> <%:Html.DropDownList( ...

Error: R3InjectorError(Environment Injector) - Unable to inject MsalService into MsalService due to NullInjectorError: MsalService provider not found

Can someone help me understand why I am getting this error when trying to integrate MSAL into my Angular app? ERROR NullInjectorError: R3InjectorError(Environment Injector)[MsalService -> MsalService]: NullInjectorError: No provider for MsalService! ...

I want to add an LI element to a UL by utilizing jQuery in forms.js

I have several forms on my webpage and I am utilizing jQuery form.js to save each comment that users post. After saving the comment successfully, I want to append it to the UL tag. Although the saving part is functioning properly, I am encountering difficu ...

What methods can a Java application use to distinguish one browser from another?

Is there a way to determine if the browser being used is Firefox or Chrome? I am looking to create an application that will only run on a specific browser registered by a user. To achieve this, my application needs to be able to identify which browser the ...

Booking.com's embedded content is experiencing display issues

My current project involves adding a booking.com embedded widget. Initially, when accessing the main page, everything works perfectly - the map and booking widget are visible for ordering. However, if you switch views without leaving the page or closing th ...

What's the best way to add animation to the send icon while hovering over the button?

<div class="text-center"> <button [disabled]="btnStatus" class="btn btn-secondary buttonSend" type="submit"> <div [hidden]="btnStatus"> Send Message&nbsp;&nbs ...

What is the best way to emphasize when the path matches exactly with '/'?

Is there a way to highlight the path only when it exactly matches '/'? Currently, even on 'Page 2', the 'Home' link is still highlighted. Check out the plunker here .active { color: red; } <a routerLinkActive="active" r ...

Guide on deploying Angular 9 SSR app on Internet Information Services

After upgrading my Angular 7 project to Angular 9, I successfully executed the commands "ng add @nguniversal/express-engine", “npm run build:ssr" and "npm run serve:ssr” in my local environment. The deployment to IIS on the web server created a "dist" ...

Switch the designation to Hover Class

I am working with nested divs and have assigned a CSS class to one of the inner divs. How can I trigger the hover effect of the class (class.hover) when the user hovers over the outer div, even if they are not directly over the inner div? I believe this m ...

Ways to retrieve the value of a specific key within an object nested within another object

Suppose I have a variable named x with the following structure: x = { choice1: { choice: { name: "choice1", text: "abc", key: "key1" } isChecked: true }, choice2: { choice: { name ...

Managing window popups using WDIO - tips and tricks

Having some trouble handling a facebook auth dialog popup through webdriverio. Struggling to target the email and password fields for the facebook signup process. Below is the code in question: it('redirects after signup', () => { browse ...

Nested components knockout knockout knockout! The $(document).ready() function fires off before the nested component is even loaded

I am faced with a situation where I have multiple nested knockout components in my code: <component1> <component2> .... </component2> </component1> The issue here is that while component1 is custom-made by me, component2 ...

Syntax error triggered and caught by ajaxError

I have implemented a client-side ajax error handler using the following code: $(document).ajaxError(processAjaxError); $.getJSON('/data.json'); In the server side, I have defined a function as shown below: def get(self): self.response.he ...

Struggling to grasp the syntax of RxJS filter

Trying to wrap my head around a filter expression in an Ionic/Angular project. Here's the code snippet: private userId$ = this.authService.currentUserAuth$.pipe( filter(user => !!user), map((user) => user.uid) ); The authservice is of ...

Exploring the power of promises in the JavaScript event loop

Just when I thought I had a solid understanding of how the event loop operates in JavaScript, I encountered a perplexing issue. If this is not new to you, I would greatly appreciate an explanation. Here's an example of the code that has left me scratc ...

Dealing with Angular API Requests and Handling Cors Exception in C# Web API

My goal is to call an API on my C# Web API from my Angular Frontend. I have attempted making the call using both HTTP and HTTPS. When using HTTP, I encounter a CORS exception. On the other hand, when using HTTPS, I receive a CONNECTION CLOSED EXCEPTION. ...