为什么 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"
}
我的 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"
}