TypeScript中setState使用prevState出现类型不匹配报错如何解决?
报错原因
你判断的方向是对的,核心有两个类型不匹配的问题:
prev参数是Test | null联合类型,当prev为null时,直接解构...prev得到的对象缺失Test接口要求的必填属性id、date、location,不符合setCurrentTest要求返回的Test | null类型Test接口的elements是可选属性,值可能为undefined,直接解构...prev.elements会触发类型错误
解决方法
根据你的业务场景选择对应方案即可:
方案1:业务逻辑保证调用 handleSubmitForm 时 currentTest 一定不为null
在更新逻辑前加上非空判断,同时给elements加空数组兜底,修正后的代码如下:
const handleSubmitForm = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); const { id, name } = results; const referenceFrom = Number(results.referenceFrom); const referenceTo = Number(results.referenceTo); const result = Number(results.result); if ( id && name && referenceFrom > 0 && referenceTo > 0 && referenceFrom < referenceTo && result > 0 ) { setCurrentTest((prev) => { // 加非空判断,TS会自动收窄类型为Test if (!prev) return prev; return { ...prev, // elements为undefined时兜底空数组 elements: [...(prev.elements ?? []), { id, name, referenceFrom, referenceTo, result }] } }); } };
方案2:允许prev为null时初始化新的Test对象
如果业务上允许提交时还没有创建Test实例,可以在prev为null时返回符合Test接口的初始化对象:
setCurrentTest((prev) => { const newElement = { id, name, referenceFrom, referenceTo, result }; if (!prev) { // 这里填入你业务对应的初始必填字段值 return { id: 1, // 替换为实际生成的id date: new Date(), location: '默认位置', // 替换为实际值 elements: [newElement] } } return { ...prev, elements: [...(prev.elements ?? []), newElement] } });
可选优化:如果elements默认是空数组,可以修改接口定义
如果业务上Test实例的elements默认就是空数组,可以直接把接口的可选属性改为必填,初始化useState的时候给elements默认值,减少后续的兜底判断:
export interface Test { id: number; date: Date; location: string; elements: Element[]; // 去掉可选标记 } // 初始化useState的时候如果有初始Test实例,直接给默认空数组 const [currentTest, setCurrentTest] = useState<Test | null>({ id: 0, date: new Date(), location: '', elements: [] });
内容的提问来源于stack exchange,提问作者Przemo256
相关产品推荐
相关产品推荐

