React+TypeScript中setLikedGadgets回调更新报错求助
问题场景
使用React的useState结合回调参数更新状态时,调用setLikedGadgets((prev: Phone[]) => [...prev, info])出现类型错误,但直接传入数组setLikedGadgets([...likedGadgets, info])可正常运行。由于setLikedGadgets的类型由上下文定义为(value: Phone[]) => void且无法修改,需要找到TypeScript中正确使用回调更新状态的方式。
错误信息
Argument of type '(prev: Phone[]) => Phone[]' is not assignable to parameter of type 'Phone[]'. Type '(prev: Phone[]) => Phone[]' is missing the following properties from type 'Phone[]': pop, push, concat, join, and 28 more.
相关代码
useLikes钩子代码
import { useContext } from 'react'; import { likedContext } from '../context/LikedContext'; import { Phone } from '../types/Phone'; export const useLikes = () => { const { likedGadgets, arrayOfLiked, setLikedGadgets, setArrayOfLiked, } = useContext(likedContext); const addToLiked = (info: Phone) => { if (arrayOfLiked.includes(info.id)) { return; } if (arrayOfLiked.length === 0) { setLikedGadgets([info]); setArrayOfLiked([info.id]); } else { setLikedGadgets((prev: Phone[]) => [...prev, info]); } }; return { addToLiked }; };
上下文类型定义
type LikedContextInterface = { likedGadgets: Phone[]; setLikedGadgets: (value: Phone[]) => void; arrayOfLiked: string[]; setArrayOfLiked: (value: string[]) => void; };
解决方案
错误根源是上下文的类型定义没有匹配React原生useState setter的类型(原生支持值或回调两种参数)。由于无法修改上下文类型,可通过类型断言将setLikedGadgets转换为正确的React状态更新器类型:
修改后的addToLiked函数:
const addToLiked = (info: Phone) => { if (arrayOfLiked.includes(info.id)) { return; } // 将setter断言为支持回调的React状态更新器类型 const updateLikedGadgets = setLikedGadgets as React.Dispatch<React.SetStateAction<Phone[]>>; if (arrayOfLiked.length === 0) { updateLikedGadgets([info]); setArrayOfLiked([info.id]); } else { updateLikedGadgets((prev) => [...prev, info]); } };
原理说明
React的React.Dispatch<React.SetStateAction<T>>类型天然支持两种参数形式:
- 直接传入
T类型的新状态值 - 传入一个接收旧状态
prevState: T并返回新状态T的回调函数
通过类型断言,我们告诉TypeScript当前的setLikedGadgets实际符合原生setter的类型,从而允许使用回调方式安全更新状态,同时保留类型检查能力。
内容的提问来源于stack exchange,提问作者Paul Gutsal

