如何在localStorage中声明类型?解决TS类型不匹配报错
解决localStorage getItem的TypeScript类型不匹配报错
报错信息
Argument of type 'string | null' is not assignable to parameter of type 'string'.
Type 'null' is not assignable to type 'string'.ts(2345)
var localStorage: Storage
原问题代码
const getLocalStorage = () => { let groceryList = localStorage.getItem('grocery-list'); if (groceryList) { return (groceryList = JSON.parse(localStorage.getItem('grocery-list'))); } else { return []; } }; function App() { const [list, setList] = useState(getLocalStorage()); useEffect(() => { localStorage.setItem('grocery-list', JSON.stringify(list)); }, [list]); }
问题原因
- 你已经通过
if (groceryList)做了类型守卫,确认groceryList是string类型,但后续又重新调用localStorage.getItem('grocery-list'),TypeScript无法保证这个新调用的返回值不是null,因此报错。 - 没有给函数返回值和状态变量声明明确的类型,TypeScript无法推断出正确的类型边界。
解决方案
1. 复用已做类型守卫的变量
直接使用已经判断过的groceryList变量,避免重复调用getItem,让TypeScript确认其类型为string:
const getLocalStorage = () => { let groceryList = localStorage.getItem('grocery-list'); if (groceryList) { return JSON.parse(groceryList); } else { return []; } };
2. 声明明确的类型(更规范的做法)
先定义杂货列表项的类型,再给函数和状态指定类型,增强代码可读性和类型安全性:
// 定义杂货项的类型,如果是复杂对象可以扩展 type GroceryItem = string; const getLocalStorage = (): GroceryItem[] => { let groceryList = localStorage.getItem('grocery-list'); if (groceryList) { // 可以添加类型断言确保解析结果符合预期 return JSON.parse(groceryList) as GroceryItem[]; } else { return []; } }; function App() { const [list, setList] = useState<GroceryItem[]>(getLocalStorage()); useEffect(() => { localStorage.setItem('grocery-list', JSON.stringify(list)); }, [list]); }
3. 不推荐:使用非空断言
如果能确保localStorage.getItem('grocery-list')在if判断后一定不为null,可以用!非空断言,但这种方式跳过了TypeScript的类型检查,存在运行时风险:
const getLocalStorage = () => { let groceryList = localStorage.getItem('grocery-list'); if (groceryList) { return JSON.parse(localStorage.getItem('grocery-list')!); } else { return []; } };
内容的提问来源于stack exchange,提问作者Mahmudul Amin Fahim
相关产品推荐
相关产品推荐

