React Reducer遇TS2322错误:boolean类型无法赋值给IArrowState
React Reducer TS2322 类型错误问题解决
问题描述
编写的React Reducer代码出现TS2322错误:Type 'boolean' is not assignable to type 'IArrowState',错误定位在const arrowReducer: Reducer<IArrowState, ArrowAction>行。
原代码
import { useReducer, Reducer } from 'react'; interface IArrowState { ascending: [ { time: boolean }, { user: boolean } ] } type ArrowAction = { type: string; } const Events: FC<IEventComponent> & {getLayout: (params: any) => void;} = () => { const arrowInitialState: IArrowState = { ascending: [ { time: true }, { user: true } ] } const arrowReducer: Reducer<IArrowState, ArrowAction> = (state, action) => { switch (action.type) { case 'time': return state.ascending['time'] = !state.ascending['time']; case 'user': return state.ascending['user'] = !state.ascending['user']; } } }
问题原因
- 返回类型不匹配:Reducer要求返回完整的
IArrowState类型对象,但当前代码中,return state.ascending['time'] = !state.ascending['time']这种写法返回的是赋值操作的结果(布尔值),和Reducer要求的返回类型不符,直接触发TS类型错误。 - 违反不可变原则:直接修改原
state对象的属性,不符合React useReducer的状态更新规则,会导致组件无法正确响应状态变化。 - 状态结构设计不合理:
IArrowState中的ascending被定义为数组,但代码中却用对象属性名('time'/'user')访问,数组应该通过索引(如ascending[0].time)访问,这里的结构设计和实际使用矛盾。
解决方案
- 调整状态结构:把
ascending从数组改为对象,符合按key访问的使用场景。 - 正确返回新状态:Reducer必须返回新的状态对象,通过解构原state来实现不可变更新。
- 完善Action类型:将
ArrowAction的type定义为联合类型,提升类型安全性。
修正后的代码
import { useReducer, Reducer, FC } from 'react'; // 假设IEventComponent是已定义的接口 interface IEventComponent {} interface IArrowState { ascending: { time: boolean; user: boolean; }; } // 更精确的Action类型 type ArrowAction = | { type: 'time' } | { type: 'user' }; const Events: FC<IEventComponent> & { getLayout: (params: any) => void } = () => { const arrowInitialState: IArrowState = { ascending: { time: true, user: true, }, }; const arrowReducer: Reducer<IArrowState, ArrowAction> = (state, action) => { switch (action.type) { case 'time': // 返回新的状态对象,不可变更新 return { ...state, ascending: { ...state.ascending, time: !state.ascending.time, }, }; case 'user': return { ...state, ascending: { ...state.ascending, user: !state.ascending.user, }, }; // 默认返回原状态,避免未覆盖的case导致错误 default: return state; } }; // 调用useReducer关联状态与Reducer const [state, dispatch] = useReducer(arrowReducer, arrowInitialState); return null; // 根据实际组件逻辑返回对应JSX };
补充说明
- 不需要额外为
Reducer<IArrowState, ArrowAction>指定返回类型,因为Reducer泛型已经明确了状态类型和Action类型,其返回值就是第一个泛型参数的类型(IArrowState)。 - 必须处理所有Action类型的case,或者添加default分支返回原状态,避免出现未覆盖的情况导致类型错误。
内容的提问来源于stack exchange,提问作者one-hand-octopus
相关产品推荐
相关产品推荐

