【问题标题】:Is is possible to use an typescript Union type for the state of a Redux Toolkit Slice?是否可以对 Redux Toolkit Slice 的状态使用 typescript Union 类型?
【发布时间】:2022-06-22 21:47:02
【问题描述】:

我想在使用 Redux Toolkit 时使用这样的联合类型来表示切片的状态:

type AppState = { loading: true } | { loading: false; data: number };

似乎在 reducer 文件中使用 Immerjs 使我无法在两个 Union 选项之间切换,例如:

import { createSlice, PayloadAction } from "@reduxjs/toolkit";

const initialState: AppState = { loading: true };

export const sampleSlice = createSlice({
  name: "sample",
  initialState,
  reducers: {
    setup: (state) => {
      return { loading: false, data: 5 };
    },
  },
});

这给了我以下 Typescript 错误:

Type '(state: WritableDraft<{ loading: true; }>) => { loading: false; data: number; }' is not assignable to type 'CaseReducer<{ loading: true; }, { payload: any; type: string; }> | CaseReducerWithPrepare<{ loading: true; }, PayloadAction<any, string, any, any>>'.

有什么办法可以做到这一点吗?我目前的解决方法是不使用联合类型来表示状态,但我想知道是否有解决方法。我也尝试过不使用布尔值,而是对 loading 键使用字符串文字,但它会产生相同的错误。

【问题讨论】:

    标签: javascript reactjs typescript redux-toolkit


    【解决方案1】:

    注意:根据文档,选项 2 是更好的方法。

    选项 1。为createSlice 提供通用参数类型。

    import { createSlice, SliceCaseReducers } from '@reduxjs/toolkit';
    
    type AppState = { loading: true } | { loading: false; data: number };
    
    const initialState: AppState = { loading: true };
    
    type CaseReducers = SliceCaseReducers<AppState>;
    
    export const sampleSlice = createSlice<AppState, CaseReducers>({
      name: 'sample',
      initialState,
      reducers: {
        setup: (state) => {
          return { loading: false, data: 5 };
        },
      },
    });
    

    state 类型 in case reducer:

    选项 2。 投射初始状态。见Defining the Initial State Type

    import { createSlice, SliceCaseReducers } from '@reduxjs/toolkit';
    
    type AppState = { loading: true } | { loading: false; data: number };
    
    const initialState: AppState = { loading: true };
    
    // type CaseReducers = SliceCaseReducers<AppState>;
    
    export const sampleSlice = createSlice({
      name: 'sample',
      initialState: initialState as AppState,
      reducers: {
        setup: (state) => {
          return { loading: false, data: 5 };
        },
      },
    });
    

    软件包版本:

    "@reduxjs/toolkit": "^1.6.1",
    "typescript": "^4.3.5",
    

    【讨论】:

    • 请不要使用选项 1。createSlice 永远不应使用手动通用注释来调用。这将删除有关操作的所有信息。资料来源:我为它写了类型。选项 2 是我们文档的建议。
    • 非常感谢!选择了 2 号选项
    猜你喜欢
    • 2021-04-22
    • 1970-01-01
    • 1970-01-01
    • 2020-11-12
    • 1970-01-01
    • 2021-06-06
    • 2020-12-14
    • 2020-12-03
    • 2022-06-12
    相关资源
    最近更新 更多