打字稿,JSON.parse 错误:“类型 'null' 不可分配给类型 'string'。”
Posted
技术标签:
【中文标题】打字稿,JSON.parse 错误:“类型 \'null\' 不可分配给类型 \'string\'。”【英文标题】:Typescript, JSON.parse error: "Type 'null' is not assignable to type 'string'."打字稿,JSON.parse 错误:“类型 'null' 不可分配给类型 'string'。” 【发布时间】:2019-07-09 22:43:54 【问题描述】:错误发生在这里:
let moonPortfolio;
...
moonPortfolio = JSON.parse(localStorage.getItem('moonPortfolio'));
我发现 this answer 是有道理的,但是在此重构之后我仍然收到该错误:
正如错误所说,localStorage.getItem() 可以返回字符串或 null。 JSON.parse() 需要一个字符串,所以你应该在尝试使用它之前测试 localStorage.getItem() 的结果。
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);
我首先将localStorage moonPortfolio
的结果设置为一个var,然后检查该var 是否为typeof
字符串。仍然收到打字稿错误?
这里有什么想法或方向吗?
【问题讨论】:
【参考方案1】:简单修复:
JSON.parse(localStorage.getItem('moonPortfolio') || '');
似乎 TS 确实知道 localStorage/sessionStorage 的内部工作原理。如果您尝试获取未设置的密钥,它将返回 null
。 null
当被视为 boolean
时是假的,因此通过添加 OR 将使用空的字符串化 json 对象,这意味着 JSON.parse(x)
将始终被赋予一个字符串,这意味着它是安全的。
【讨论】:
感谢您提供如此简单的修复!【参考方案2】:编译器不太了解localStorage.getItem
的内部工作原理,并且不会假设从getItem
的一次调用到下一次调用的返回值相同。所以它只是告诉你,在第二次调用getItem
时无法确定结果不是null
。
尝试简单地传入您已经创建的变量,而不是再次从localStorage
读取:
if (typeof storedPortfolio === 'string')
moonPortfolio = JSON.parse(storedPortfolio);
【讨论】:
谢谢! 10 分钟.... 也刚刚发现这也有效:JSON.parse(localStorage.getItem('moonPortfolio') || '');
@Leon True 并且如果在 single 空字符串的边缘情况下(JSON.parse('')
抛出 SyntaxError
),该选项可能会更安全,但我仍然会对于无效字符串,更喜欢显式类型检查和 try
/catch
。【参考方案3】:
TypeScript 不知道使用相同的字符串文字多次调用 localStorage.getItem
将始终返回相同的值(事实上,这甚至不是真的)。
对localStorage.getItem('moonPortfolio')
的第二次调用很可能会返回null
- 您应该调用JSON.parse(storedPortfolio)
而不是再次调用getItem
。
【讨论】:
null
是 JSON.parse
的有效值(不会引发错误,返回 null
) - JSON.parse
的第一个参数的类型 def 不应该是 string | null
?
不,因为 JSON.parse 的第一步是将其参数隐式强制转换为字符串。 JSON.parse(32)
“成功”出于同样的原因,但也是不允许的。
这种行为(无论是否隐含)是否应该被分型所覆盖?
没有?您不希望 parseInt(true) 没有类型错误。见***.com/questions/41750390/…
我想说返回 NaN
与返回变量值不同 - 尽管如此,您在该问题中所写的内容似乎可以作为文档,并清楚地概述了 TypeScript 做什么和不做什么.【参考方案4】:
要知道的主要事情是 localStorage.getItem() 返回字符串 |空值。知道我们可以用更简单的模式重写代码:
const portfolio = []; //Just to make the code samples valid
if (portfolio.length === 0)
let moonPortfolio = []; //Default value
const storedText = localStorage.getItem('moonPortfolio');
if (storedText !== null) //We know it's a string then!
moonPortfolio = JSON.parse(storedText);
//The if statement here is not needed as JSON.parse can only return
//object | array | null or throw. null is the only falsy value and that
//can only happen if storedText is null but we've already disallowed
//that.
//if (moonPortfolio)
const savedPortfolio = Object.values(moonPortfolio);
//Do whatever else is needed...
//
【讨论】:
以上是关于打字稿,JSON.parse 错误:“类型 'null' 不可分配给类型 'string'。”的主要内容,如果未能解决你的问题,请参考以下文章