Redux createSlice TypeScript类型错误修复求助
Redux Toolkit createSlice TypeScript类型错误修复方案
问题描述
使用Redux Toolkit的createSlice时遇到TypeScript类型错误,核心代码如下:
import { Conversation } from "@/types/conversation"; import { PayloadAction, createSlice } from "@reduxjs/toolkit"; const initialState: Conversation | null = null; export const conversationSlice = createSlice({ name: "conversation", initialState, reducers: { setConversation: ( // type error state: Conversation | null, action: PayloadAction<Conversation> ) => { state = action.payload; return state; }, }, }); export const { setConversation } = conversationSlice.actions; export default conversationSlice.reducer;
收到的错误信息:
Type '(state: Conversation | null, action: PayloadAction<Conversation>) => Conversation' is not assignable to type 'CaseReducer<null, { payload: any; type: string; }> | CaseReducerWithPrepare<null, PayloadAction<any, string, any, any>>'. Type '(state: Conversation | null, action: PayloadAction<Conversation>) => Conversation' is not assignable to type 'CaseReducer<null, { payload: any; type: string; }>'. Type 'Conversation' is not assignable to type 'void'.ts(2322)
已知createSlice底层基于Immer实现:
- 移除
return语句后类型错误消失,但reducer无法正常更新状态 - 保留
return语句时功能正常,但存在类型错误 - 尝试使用
Draft类型标注state仍报错:
import { Draft, PayloadAction, createSlice } from "@reduxjs/toolkit"; interface Conversation { any_data: string[]; } const initialState: Conversation | null = null; export const conversationSlice = createSlice({ name: "conversation", initialState, reducers: { setConversation: ( // type error state: Draft<Conversation | null>, action: PayloadAction<Conversation> ) => action.payload, }, }); export const { setConversation } = conversationSlice.actions; export default conversationSlice.reducer;
修复方案
方法1:让Redux Toolkit自动推断状态类型
不要手动指定state的类型,让Redux Toolkit根据initialState自动推断,直接返回新状态即可:
import { Conversation } from "@/types/conversation"; import { PayloadAction, createSlice } from "@reduxjs/toolkit"; const initialState: Conversation | null = null; export const conversationSlice = createSlice({ name: "conversation", initialState, reducers: { setConversation: (state, action: PayloadAction<Conversation>) => { return action.payload; }, }, }); export const { setConversation } = conversationSlice.actions; export default conversationSlice.reducer;
方法2:显式指定Slice泛型参数
如果需要更明确的类型控制,可给createSlice指定泛型,明确状态类型和reducer的返回值类型:
import { Conversation } from "@/types/conversation"; import { PayloadAction, createSlice } from "@reduxjs/toolkit"; type ConversationState = Conversation | null; const initialState: ConversationState = null; export const conversationSlice = createSlice<ConversationState, { setConversation: (state: ConversationState, action: PayloadAction<Conversation>) => ConversationState; }>({ name: "conversation", initialState, reducers: { setConversation: (state, action) => { return action.payload; }, }, }); export const { setConversation } = conversationSlice.actions; export default conversationSlice.reducer;
错误原因解析
- 手动指定
state: Conversation | null时,TypeScript会要求reducer返回值与初始状态类型完全匹配,但返回的Conversation与Conversation | null存在类型差异,加上Immer的内部类型机制,导致冲突报错。 - 使用
Draft<Conversation | null>标注state时,返回的原始Conversation类型无法与Immer的包装Draft类型兼容,因此报错。
内容的提问来源于stack exchange,提问作者user13102023
相关产品推荐
相关产品推荐

