You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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'];
    }
  }
}

问题原因

  1. 返回类型不匹配:Reducer要求返回完整的IArrowState类型对象,但当前代码中,return state.ascending['time'] = !state.ascending['time']这种写法返回的是赋值操作的结果(布尔值),和Reducer要求的返回类型不符,直接触发TS类型错误。
  2. 违反不可变原则:直接修改原state对象的属性,不符合React useReducer的状态更新规则,会导致组件无法正确响应状态变化。
  3. 状态结构设计不合理:IArrowState中的ascending被定义为数组,但代码中却用对象属性名('time'/'user')访问,数组应该通过索引(如ascending[0].time)访问,这里的结构设计和实际使用矛盾。

解决方案

  1. 调整状态结构:把ascending从数组改为对象,符合按key访问的使用场景。
  2. 正确返回新状态:Reducer必须返回新的状态对象,通过解构原state来实现不可变更新。
  3. 完善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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 11:10:50