Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript, JSON.parse error: "Type 'null' is not assignable to type 'string'."

The error was happening here:

let moonPortfolio;
...
moonPortfolio = JSON.parse(localStorage.getItem('moonPortfolio'));

I found this answer which makes sense, however I'm still getting that error after this refactor:

As the error says, localStorage.getItem() can return either a string or null. JSON.parse() requires a string, so you should test the result of localStorage.getItem() before you try to use it.

if (portfolio.length === 0) {
  const storedPortfolio = localStorage.getItem('moonPortfolio');

  if (typeof storedPortfolio === 'string') {
    moonPortfolio = JSON.parse(localStorage.getItem('moonPortfolio'));
  }
  else {
    moonPortfolio = [];
  }

  if (moonPortfolio) {
    const savedPortfolio = Object.values(moonPortfolio);
    this.props.fetchAllAssets();
    // this.props.addCoins(savedPortfolio);
  }
}

enter image description here

I first set the results of localStorage moonPortfolio to a var, then check if the var is typeof string. Yet still getting the typescript error?

Any thoughts or direction here?

like image 544
Leon Gaban Avatar asked Feb 15 '19 18:02

Leon Gaban


2 Answers

Simple fix:

JSON.parse(localStorage.getItem('moonPortfolio') || '{}');

Seems like TS does know about the inner workings of localStorage/sessionStorage actually. It returns null if you try to fetch a key that isn't set. null when treated as boolean is falsy so by adding OR the empty stringified json object will be used instead meaning that JSON.parse(x) will always be given a string meaning it's then type safe.

like image 78
OZZIE Avatar answered Oct 21 '22 06:10

OZZIE


The compiler doesn't know too much about the inner workings of localStorage.getItem and doesn't make the assumption that the return value will be the same from one call of getItem to the next. So it just tells you that it can't be certain that on the second call to getItem the result isn't null.

Try simply passing in the variable you've already created instead of reading from localStorage again:

if (typeof storedPortfolio === 'string') {
  moonPortfolio = JSON.parse(storedPortfolio);
}
like image 38
p.s.w.g Avatar answered Oct 21 '22 07:10

p.s.w.g