使用 preloadedState 时生成 Redux Toolkit TypeScript 类型
Generating Redux Toolkit TypeScript types when using preloadedState
我正在尝试设置我的测试环境,其中包括 React 测试库、Redux 工具包、RTK 查询和 TypeScript,但我 运行 遇到了一个我无法解决的问题。
我想不通的主要问题是如何在提供 preloadedState
.
时生成 AppDispatch
类型 as explained in the documentation here
按照 RTK 文档直接使用 configureStore()
没问题,因为商店是在模块内部创建的:
const store = configureStore({
reducer: {
home: homeReducer,
[homeApi.reducerPath]: homeApi.reducer,
},
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(
homeApi.middleware,
),
});
export type RootState = ReturnType<typeof store.reducer>;
export type AppDispatch = typeof store.dispatch; // not a problem as store exists here
export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
export default store;
但是,这样做很难将 preloadedState
值传递给 configureStore()
并保留生成的类型。如果我提取减速器并使用 combineReducers()
我可以从那里生成 RootState
,但我仍然无法弄清楚如何导出 AppDispatch
因为 store.dispatch
直到商店已创建,为了通过 preloadedState
我需要延迟商店的创建。
export const rootInitialState: Pick<RootState, 'home'> = {
home: homeInitialState,
};
const reducer = combineReducers({
home: homeReducer,
[homeApi.reducerPath]: homeApi.reducer,
});
export type RootState = ReturnType<typeof reducer>;
// this is the problem as store is created externally to this module,
// so how can I extract this type now?
export type AppDispatch = typeof store.dispatch;
export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
export const createStore = (preloadedState: Partial<RootState>) => configureStore({
reducer,
preloadedState,
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(
homeApi.middleware,
),
});
这真的可以做到吗?在这一点上,我完全被难住了,所以如果有人能提供解决方案或让我摆脱痛苦,我将不胜感激。
很简单,你只需要改变文件中声明的顺序并增加一个检查级别。
关键是虽然我们还没有真正的商店,但我们确实有 createStore
,其中 returns 是新的商店实例。 TS 可以计算出“这个函数返回值的类型”,所以我们可以用它来代替:
export const createStore = (preloadedState: Partial<RootState>) => configureStore({
reducer,
preloadedState,
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(
homeApi.middleware,
),
});
// 1) Take the type of `createStore`
// 2) Figure out the return type of that function, which is a store
// 3) Look up the type of the `dispatch` field in that returned store type
export type AppDispatch = ReturnType<typeof createStore>['dispatch'];
我正在尝试设置我的测试环境,其中包括 React 测试库、Redux 工具包、RTK 查询和 TypeScript,但我 运行 遇到了一个我无法解决的问题。
我想不通的主要问题是如何在提供 preloadedState
.
AppDispatch
类型 as explained in the documentation here
按照 RTK 文档直接使用 configureStore()
没问题,因为商店是在模块内部创建的:
const store = configureStore({
reducer: {
home: homeReducer,
[homeApi.reducerPath]: homeApi.reducer,
},
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(
homeApi.middleware,
),
});
export type RootState = ReturnType<typeof store.reducer>;
export type AppDispatch = typeof store.dispatch; // not a problem as store exists here
export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
export default store;
但是,这样做很难将 preloadedState
值传递给 configureStore()
并保留生成的类型。如果我提取减速器并使用 combineReducers()
我可以从那里生成 RootState
,但我仍然无法弄清楚如何导出 AppDispatch
因为 store.dispatch
直到商店已创建,为了通过 preloadedState
我需要延迟商店的创建。
export const rootInitialState: Pick<RootState, 'home'> = {
home: homeInitialState,
};
const reducer = combineReducers({
home: homeReducer,
[homeApi.reducerPath]: homeApi.reducer,
});
export type RootState = ReturnType<typeof reducer>;
// this is the problem as store is created externally to this module,
// so how can I extract this type now?
export type AppDispatch = typeof store.dispatch;
export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
export const createStore = (preloadedState: Partial<RootState>) => configureStore({
reducer,
preloadedState,
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(
homeApi.middleware,
),
});
这真的可以做到吗?在这一点上,我完全被难住了,所以如果有人能提供解决方案或让我摆脱痛苦,我将不胜感激。
很简单,你只需要改变文件中声明的顺序并增加一个检查级别。
关键是虽然我们还没有真正的商店,但我们确实有 createStore
,其中 returns 是新的商店实例。 TS 可以计算出“这个函数返回值的类型”,所以我们可以用它来代替:
export const createStore = (preloadedState: Partial<RootState>) => configureStore({
reducer,
preloadedState,
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(
homeApi.middleware,
),
});
// 1) Take the type of `createStore`
// 2) Figure out the return type of that function, which is a store
// 3) Look up the type of the `dispatch` field in that returned store type
export type AppDispatch = ReturnType<typeof createStore>['dispatch'];