React+TypeScript中map遍历数组、访问error.message报never类型错误如何解决
问题根源
两个报错本质都是 TypeScript 无法从useState的初始值推导出正确的类型:
const [items, setItems] = useState([])初始值是空数组,TS 会默认推导类型为never[],自然无法访问item.id等属性const [error, setError] = useState(null)初始值是null,TS 推导类型为null,自然无法访问error.message属性
正确解决步骤
1. 定义数组元素的类型
先根据你代码中访问的字段,定义列表项的接口,后续如果接口返回字段有变化,直接调整这个接口即可:
interface Item { id: number | string; // 可根据实际接口返回的id类型调整 name: string; price: number; }
2. 给useState添加泛型约束
给两个有类型问题的状态指定泛型,既兼容初始值,也符合后续赋值的类型要求:
// 错误状态可能是null,也可能是Error实例 const [error, setError] = useState<Error | null>(null); const [isLoaded, setIsLoaded] = useState(false); // 列表是Item类型的数组,初始空数组符合类型要求 const [items, setItems] = useState<Item[]>([]);
3. 给请求返回值加类型断言
fetch返回的结果默认是unknown类型,我们确认结构匹配的前提下可以加断言避免隐式any报错:
setItems(result as Item[]); setError(error as Error);
完整修改后的代码参考
import React, {useState, useEffect} from 'react'; import logo from './logo.svg'; import './App.css'; interface Item { id: number | string; name: string; price: number; } function App() { const [error, setError] = useState<Error | null>(null); const [isLoaded, setIsLoaded] = useState(false); const [items, setItems] = useState<Item[]>([]); useEffect(() => { fetch("https://api.publicapis.org/entries") .then(res => res.json()) .then( (result) => { setIsLoaded(true); setItems(result as Item[]); }, (error) => { setIsLoaded(true); setError(error as Error); } ) }, []) if (error) { return <div>Error: {error.message}</div>; } else if (!isLoaded) { return <div>Loading...</div>; } else { return ( <ul> {items.map((item) => ( <li key={item.id}> {item.name} {item.price} </li> ))} </ul> ); } } export default App;
内容的提问来源于stack exchange,提问作者Dazeh
相关产品推荐
相关产品推荐

