带有 TypeScript 的 Redux 工具包 - 使用像 Gatsby 这样的 SSR 框架输入 RootState

Redux Toolkit with TypeScript - typing RootState with an SSR framework like Gatsby

the official Redux Toolkit docs建议输入RootState如下:

import { configureStore } from '@reduxjs/toolkit'
// ...

export const store = configureStore({
  reducer: {
    posts: postsReducer,
    comments: commentsReducer,
    users: usersReducer,
  },
})

// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof store.getState>
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch

但是,当将 Redux 与服务端渲染 (SSR) 框架(如 Gatsby)一起使用时,我需要将我的 configureStore 调用导出为可调用函数,因此我可以确定它只被实例化一次:

import { configureStore } from '@reduxjs/toolkit'
// ...

// 'store' is recommended by the gatsby team to be a function,
// See https://github.com/gatsbyjs/gatsby/blob/master/examples/using-redux/wrap-with-provider.js
export const store = () => configureStore({
  reducer: {
    posts: postsReducer,
    comments: commentsReducer,
    users: usersReducer,
  },
})

// TODO: won't work because store is not a const anymore, it is a function!
// Infer the `RootState` and `AppDispatch` types from the store itself
// export type RootState = ReturnType<typeof store.getState>
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
// export type AppDispatch = typeof store.dispatch

任何人都知道我如何调和保持配置存储调用函数(遵循 Gatsby 最佳实践),但仍然以某种方式输出 RootState(所以我可以使用 useSelector在我的应用程序中)?

抓住你的帽子:

type ConfiguredStore = ReturnType<typeof store>;
type StoreGetState = ConfiguredStore["getState"];
export type RootState = ReturnType<StoreGetState>;
export type AppDispatch = ConfiguredStore["dispatch"];

附带说明一下,我建议将该函数命名为 makeStore 或类似的名称,而不仅仅是将其命名为 store.