如何在TypeScript中用createSlice创建无需prepare函数的reducer
解决Redux Toolkit createSlice的TypeScript类型问题(无需prepare函数)
问题根源
TypeScript要求你提供prepare函数,本质是因为它无法正确推断action payload的类型。只要明确payload类型,就能避免这个强制要求。
方案1:用PayloadAction明确payload类型
直接在reducer函数中通过PayloadAction指定payload的类型,让TypeScript正确推断,无需额外prepare函数:
import { createSlice, PayloadAction } from '@reduxjs/toolkit'; // 先定义业务类型 interface Hero { id: number; name: string; } interface FavoritesState { favorites: Hero[]; } const initialState: FavoritesState = { favorites: [], }; const favoritesSlice = createSlice({ name: 'favorites', initialState, reducers: { // 直接定义reducer,用PayloadAction指定payload类型 addFavoriteHeroes: (state, action: PayloadAction<Hero[]>) => { // 直接修改Immer包装的state state.favorites.push(...action.payload); }, }, }); export const { addFavoriteHeroes } = favoritesSlice.actions; export default favoritesSlice.reducer;
方案2:显式指定CaseReducer类型
如果需要将reducer单独提取,可以给它指定CaseReducer类型,同样不需要prepare:
import { createSlice, CaseReducer, PayloadAction } from '@reduxjs/toolkit'; // 类型定义同上 interface Hero { /* ... */ } interface FavoritesState { /* ... */ } // 单独定义reducer并指定类型 const addFavoriteHeroes: CaseReducer<FavoritesState, PayloadAction<Hero[]>> = (state, action) => { state.favorites.push(...action.payload); }; const favoritesSlice = createSlice({ name: 'favorites', initialState: { favorites: [] as Hero[] }, reducers: { addFavoriteHeroes, }, });
解决state为Proxy对象的查看问题
RTK用Immer包装state时,直接console.log(state)会输出Proxy,用RTK自带的current函数可以获取原始状态:
import { createSlice, PayloadAction, current } from '@reduxjs/toolkit'; // 在reducer中使用current addFavoriteHeroes: (state, action: PayloadAction<Hero[]>) => { // 打印原始state对象,而非Proxy console.log(current(state)); state.favorites.push(...action.payload); },
内容的提问来源于stack exchange,提问作者Богдан Гапоненко
相关产品推荐
相关产品推荐

