React解析JSON文件报错:'string | ArrayBuffer | null'无法赋值给string类型
React+TypeScript中FileReader读取JSON文件的类型错误解决
问题场景
使用FileReader.readAsText读取本地JSON文件后,执行JSON.parse(fileReader.result)时触发TypeScript错误,错误提示:
Argument of type 'string | ArrayBuffer | null' is not assignable to parameter of type 'string'. Type 'null' is not assignable to type 'string'. TS2345
移除JSON.parse能得到字符串数据,但需要将其转为对象类型。
错误原因
TypeScript对FileReader.result的类型定义为string | ArrayBuffer | null,而JSON.parse()仅接受string类型参数。即使使用readAsText方法后result实际是字符串类型,TS仍会严格检查类型匹配,因此直接传入会报错。
解决方案
在调用JSON.parse前,先对fileReader.result做类型校验,确保其为字符串类型:
- 用
typeof判断结果是否为string,排除null和ArrayBuffer的情况 - 配合
try/catch捕获JSON解析错误,避免非法JSON内容导致崩溃
修改后的代码
import { useState, useRef, Fragment } from 'react'; import logo from './logo.svg'; const App = () => { const [file, setFile] = useState<File | undefined>(); const fileRef = useRef<HTMLInputElement>(null); const onChangeFile = (e: React.ChangeEvent<HTMLInputElement>) => { if (e.target.files && e.target.files[0]) { const selectedFile = e.target.files[0]; setFile(selectedFile); const fileReader = new FileReader(); fileReader.onload = function() { if (typeof fileReader.result === 'string') { try { const userObj = JSON.parse(fileReader.result); console.log(userObj); console.log(typeof userObj); // 此处可将转换后的对象存入state或做其他处理 // setData(userObj); } catch (error) { console.error('JSON解析失败:', error); } } }; fileReader.readAsText(selectedFile); } }; return ( <Fragment> <div className='App'> <header className='App-header'> <img src={logo} className='App-logo' alt='logo' /> <h1 className='App-title'>Welcome to JSON Forms with React</h1> <p className='App-intro'>More Forms. Less Code.</p> </header> </div> <input type='file' id='input_json' ref={fileRef} onChange={onChangeFile} accept='application/json' /> </Fragment> ); }; export default App;
额外优化点
- 给
useState和useRef添加明确类型注解,提升代码可读性与TS检查能力 - 给input添加
accept='application/json'属性,限制用户仅能选择JSON文件 - 增加错误捕获逻辑,避免非法JSON文件导致页面崩溃
内容的提问来源于stack exchange,提问作者Andrei K
相关产品推荐
相关产品推荐

