How do I resolve this Typescript issue?
const userData: {
email: string;
id: string;
_token: string;
_tokenExpirationDate: string;
} = JSON.parse(localStorage.getItem('userData'));
Message from Console
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 added the // @ts-ignore but WebStorm is complaining that there is an error.
CodePudding user response:
Let's ignore the fact that JSON.parse()
's call signature declaration returns the unsafe any
type. I'll just assume that if JSON.parse()
returns anything other than null
, it will be a value of your expected object type.
It's possible that localStorage.getItem("userData")
might be null
, and TypeScript thinks that it's a mistake to call JSON.parse(null)
, since generally the point of JSON.parse()
is to parse strings that encode JSON values. Parsing null
is therefore a type error, even though JavaScript will not have a runtime error. See What does "all legal JavaScript is legal TypeScript" mean? for more information.
If you're trying to fix it to be more type safe, you should make sure only to pass a string
. Perhaps 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 error, and now userData
has the type {email: string ... } | null
, where the union with the null
type reflects that userData
might either be a valid object or null
.
If you want to be expedient but a little less safe, you could just lie to the compiler about the local storage result and assert that it is 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 I added the | null
manually there, since the compiler can't see that possibility anymore.
CodePudding user response:
The easiest way to solve your problem IMO is to just do this:
const userData: {
email: string;
id: string;
_token: string;
_tokenExpirationDate: string;
} = JSON.parse(localStorage.getItem('userData') ?? "null");
Note the nullish coalascing operator (??
) requires typescript 3.7
Now in the case that you want your type to reflect the possibility of being null (in case localStorage does not contain 'userData'
), then you probably want to use a union type with null
:
const userData: {
email: string;
id: string;
_token: string;
_tokenExpirationDate: string;
} | null = JSON.parse(localStorage.getItem('userData') ?? "null");
At this point, you might as well extract that userData
type to an interface:
interface UserData {
email: string;
id: string;
_token: string;
_tokenExpirationDate: string;
}
const userData: UserData | null = JSON.parse(localStorage.getItem('userData') ?? "null");