TypeScript配合React useReducer时reducer抛出TS2366错误如何解决?
报错的根本原因是TypeScript判定你的reducer函数存在没有返回符合声明类型的执行路径,具体问题和修复方案如下:
问题原因
- Action类型定义和实际传值不匹配:
SUCCESS_GET类型的payload你定义为单个Sensor类型,但实际调用dispatch({ type: 'SUCCESS_GET', payload: res.data })时,后端返回的res.data是传感器数组Sensor[],类型不匹配导致TS认为存在未被switch分支覆盖的action场景,即使有default抛出错误,也会触发缺少返回的报错。 - 基础类型误用大写包装对象:
InitialStateType里用了大写的Boolean、String类型,这是JS的包装对象类型,和你实际使用的基础类型boolean、string不兼容,会引发额外的类型校验问题。 - 组件泛型定义错误:
ListSensors组件的FC泛型错误传入了HTMLDataListElement类型,FC的泛型是组件props的类型定义,无props的情况下不需要传泛型。 - 异步请求缺少异常捕获:如果网络请求抛出异常,不会触发你写的错误分支,会直接导致控制台报错。
修复步骤
- 修正
types.ts中SUCCESS_GET的payload类型:
// 修改前 // { type: 'SUCCESS_GET', payload: Sensor } // 修改后 { type: 'SUCCESS_GET', payload: Sensor[] }
- 修正
interfaces.ts中InitialStateType的基础类型:
export interface InitialStateType { sensors: Sensor[], loading: boolean, // 大写Boolean改小写boolean error: boolean | string // 大写Boolean、String改小写 }
- 修正
ListSensor.ts中组件的类型定义:
// 修改前 // const ListSensors: FC<HTMLDataListElement>= () => { // 修改后 const ListSensors: FC = () => {
- 给异步请求添加try/catch捕获异常(可选但推荐):
// useEffect里的loadSensors修改为 const loadSensors = async () => { try { const res = await sensorServices.getSensors(); if (res.status === 200) { dispatch({ type: 'SUCCESS_GET', payload: res.data }); return; } dispatch({ type: 'ERROR_GET', error: res.data}); } catch (err) { dispatch({ type: 'ERROR_GET', error: '网络请求失败' }); } }; // handleCreate里的createSensor同理添加try/catch const createSensor = async () => { try { const res = await sensorServices.createNewSensor(objectSensor); if (res.status === 200) { dispatch({ type: 'SUCCESS_CREATE', payload: res.data }); return; } dispatch({ type: 'ERROR_CREATE', error: res.data}); } catch (err) { dispatch({ type: 'ERROR_CREATE', error: '创建传感器失败' }); } };
改完之后重新编译,TS2366报错就会消失,因为此时TS可以识别所有合法的Action类型,确认switch分支已经覆盖了所有可能的情况,default分支抛出错误不需要返回值,符合函数的类型声明。
内容的提问来源于stack exchange,提问作者Gabriel Caballero
相关产品推荐
相关产品推荐

