为什么 typescript 在 reduxToolkit createSlice 函数中抱怨 redux 切片的 initialState 类型,即使它是正确的类型?

Why typescript complains about redux slices' initialState type in reduxToolkit createSlice function, even though it is correct type?

我的 createSlice() 函数:

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

type TransferDeckModeType = "pipetting" | "evaluation" | "editing";

var initialState: TransferDeckModeType = "pipetting";

const transfer_deck_mode = createSlice({
  name: "transfer_deck_mode",
  initialState,
  reducers: {
    setTransferDeckMode(state, action: PayloadAction<TransferDeckModeType>) {
      let newState = action.payload;
      return newState;
    },
  },
});

export const { setTransferDeckMode } = transfer_deck_mode.actions;

export default transfer_deck_mode.reducer;

我在 setTransferDeckMode 上收到打字稿错误。

Type '(state: "pipetting", action: { payload: TransferDeckModeType; type: string; }) => TransferDeckModeType' is not assignable to type 'CaseReducer<"pipetting", { payload: any; type: string; }> | CaseReducerWithPrepare<"pipetting", PayloadAction<any, string, any, any>>'.
  Type '(state: "pipetting", action: { payload: TransferDeckModeType; type: string; }) => TransferDeckModeType' is not assignable to type 'CaseReducer<"pipetting", { payload: any; type: string; }>'.
    Type 'TransferDeckModeType' is not assignable to type 'void | "pipetting"'.
      Type '"evaluation"' is not assignable to type 'void | "pipetting"'.ts(2322)
(method) setTransferDeckMode(state: "pipetting", action: PayloadAction<TransferDeckModeType>): TransferDeckModeType

'void' 是从哪里来的?什么是将类型设置为 'void | "pipetting"'。我看不出我的状态可能在哪里无效。

我觉得我错过了在哪里声明切片的状态,但由于某种原因我是盲人。我以为可以从initialState的类型推断出来。

如果我将 initialState 类型更改为 string,错误就会消失。


var initialState: string = "pipetting";

但这没有意义 - 为什么我不能声明 initialState 的类型?

这就是RTK文档显示的原因

var initialState = "pipetting" as TransferDeckModeType ;

相反。

TypeScript 在这里做流分析。您可以在 this TypeScript Playground

中进行试验
function something<T>(initialState: T) { return { initialState } }
type Values = 'a' | 'b'

{
var initialState: Values = 'a';
//    ^?

const derivedValue = something(initialState)
//    ^?
// due to flow analysis, TS thinks `initialState` is `'a'`
// and pins `derivedValue` to `{ initialState: "a" }`
}

{
var initialState = 'a' as Values;
//    ^?

const derivedValue = something(initialState)
//    ^?
// here we could prevent that with a type assertion, 
// telling TS to stop being "too smart"
}