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

Redux Toolkit Slice 出现WritableDraft类型错误求助

解决Redux Toolkit中state属性显示WritableDraft类型的问题

问题原因

WritableDraft是Redux Toolkit内置Immer库生成的类型,用于允许你在reducer中直接"修改"状态(实际是生成不可变新状态)。出现类型不符的核心问题是初始状态类型定义与实际初始值不匹配,同时未正确处理异步action的rejected payload类型。

具体修复步骤

  1. 修正初始状态的类型定义
    你的InitialAppointmentState中data和error的类型未包含null,但初始值设置为null,这会导致TypeScript类型推断异常,进而让Immer的WritableDraft类型暴露出来。修改类型定义:
type InitialAppointmentState = {
  data: Appointment[] | null; // 允许null值
  isFetching: boolean;
  error: AppAPIError | null; // 允许null值
};
  1. 处理rejected case的payload类型
    getAppointments.rejected的action.payload可能为undefined(比如未使用rejectWithValue抛出错误时),需要添加类型检查确保赋值安全:
builder.addCase(getAppointments.rejected, (state, action) => {
  state.isFetching = false;
  // 用空值合并运算符处理payload可能为undefined的情况
  state.error = action.payload ?? null;
});
  1. 关于WritableDraft的说明
    在reducer内部看到state.data或state.error是WritableDraft类型是正常现象,这是Immer在运行时包装状态的结果。当你在组件中通过useSelector获取状态时,得到的会是你定义的原始类型(Appointment[] | null或AppAPIError | null),不会影响实际使用。

修正后的完整Slice代码示例

type InitialAppointmentState = {
  data: Appointment[] | null;
  isFetching: boolean;
  error: AppAPIError | null;
};

const initialAppointmentState: InitialAppointmentState = {
  data: null,
  isFetching: false,
  error: null
};

const appointments = createSlice({
  name: "appointments",
  initialState: initialAppointmentState,
  reducers: {
    updateAppointement(state, action: PayloadAction<Appointment>) {
      // 先判断data不为null再执行map操作
      if (state.data) {
        state.data = state.data.map((appointment) =>
          appointment.id === action.payload.id ? action.payload : appointment
        );
      }
    }
  },
  extraReducers: (builder) => {
    builder.addCase(getAppointments.fulfilled, (state, action) => {
      state.isFetching = false;
      state.data = action.payload;
    });
    builder.addCase(getAppointments.pending, (state) => {
      state.isFetching = true;
    });
    builder.addCase(getAppointments.rejected, (state, action) => {
      state.isFetching = false;
      state.error = action.payload ?? null;
    });
  }
});

内容的提问来源于stack exchange,提问作者maxi hraschan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 13:17:33