是否可以对 Redux Toolkit Slice 的状态使用打字稿联合类型?

Is is possible to use an typescript Union type for the state of a Redux Toolkit Slice?

我想在使用 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 键的字符串文字,但它会产生相同的错误。

选项 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 减速器类型:

选项 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",