Redux Toolkit使用makeStore函数时如何正确推导RootState类型
问题原因
你当前的类型推导失效核心是手动给makeStore标注的返回值类型EnhancedStore没有传入泛型参数,使用了其默认的S = any泛型值,直接覆盖了configureStore本可以自动推导的State类型,最终导致RootState被推导为any。
解决方案
最优实现分为两步:提前抽离根Reducer类型、给EnhancedStore传入准确的泛型参数,同时可以优化初始化State的类型校验:
- 先抽离组合后的根Reducer,提前定义
RootState类型 - 修正
makeStore的参数和返回值类型标注 - 后续
AppDispatch可以直接从Store实例推导类型
修改后完整代码如下:
import { configureStore, combineReducers, EnhancedStore, } from '@reduxjs/toolkit'; import createSagaMiddleware from 'redux-saga'; import { persistStore, persistReducer, FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER, } from 'redux-persist'; import storage from 'redux-persist/lib/storage'; import { cartReducer } from '@hooks'; import appReducer from './reducer'; import rootSaga from './saga'; // 抽离根Reducer,提前定义RootState类型 const rootReducer = combineReducers({ app: appReducer, cart: cartReducer }); export type RootState = ReturnType<typeof rootReducer>; // 修正makeStore的类型标注,给EnhancedStore传入RootState泛型参数 export const makeStore = (initialState?: Partial<RootState>): EnhancedStore<RootState> => { const persistConfig = { key: 'root', version: 1, storage, }; const persistedReducer = persistReducer( persistConfig, rootReducer ); const sagaMiddleware = createSagaMiddleware(); const store = configureStore({ reducer: persistedReducer, preloadedState: initialState, middleware: getDefaultMiddleware => getDefaultMiddleware({ thunk: false, serializableCheck: { ignoredActions: [ FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER, ], }, }).concat(sagaMiddleware), }); sagaMiddleware.run(rootSaga); return store; }; const store = makeStore(); export const persistor = persistStore(store); // 此时AppDispatch可以正确推导出包含saga等中间件的增强dispatch类型 export type AppDispatch = typeof store.dispatch; export default store;
补充说明
如果你不需要限制makeStore入参initialState的类型,也可以直接删掉手动标注的makeStore返回值类型,让TS自动从configureStore的返回结果推导类型,同样可以得到正确的RootState和AppDispatch,不过提前声明RootState更方便后续在其他文件中直接导入使用。
内容的提问来源于stack exchange,提问作者Prinny
相关产品推荐
相关产品推荐

