Redux-toolkit: Get `store.dispatch` type info without store creation

Created on 14 Jul 2020  路  4Comments  路  Source: reduxjs/redux-toolkit

I want to split type definition and custom hooks away from store initialization code.
I wonder if we can infer dispatch type info just from reducers, or from reducers and middlewares?

import {TypedUseSelectorHook, useDispatch, useSelector} from 'react-redux'
import {Action, configureStore, ThunkAction} from '@reduxjs/toolkit'

import {reducer} from './root-reducer'

export const store = configureStore({reducer})

if (process.env.NODE_ENV === 'development') {
  module.hot?.accept('./root-reducer', () => {
    const newReducer = require('./root-reducer').default

    store.replaceReducer(newReducer)
  })
}

// code below should be in separate file and with no store instance import
export type AppState = ReturnType<typeof reducer>
export type AppDispatch = typeof store.dispatch

export const useAppSelector: TypedUseSelectorHook<AppState> = useSelector
export const useAppDispatch = () => useDispatch<AppDispatch>()

Most helpful comment

@jnachtigall In this case, you could potentially change it to:

export type AppDispatch = ReturnType<typeof getStore>["dispatch"];

All 4 comments

@phryneas could say for sure, but as far as I know, no. You can't infer the type of dispatch without actually having a real store that's been created.

@markerikson I would need to run export const store = configureStore({reducer}) after DOMContentLoaded in order to pass a preloadedState config based on data that is not yet available.

But changing

const store = configureStore({
  reducer: rootReducer,
});

export type AppDispatch = typeof store.dispatch;

to

export const getStore = () => {
  const store = configureStore({
    reducer: rootReducer,
  });
  return store;
};

and trying to call getStore () later when data is available gives me a TypeScript error because store is undefined :-/

image

So due to this it seems impossible to defer store creation to a later point in time (when data is available).

@amankkg Have you found a workaround for this?

@jnachtigall In this case, you could potentially change it to:

export type AppDispatch = ReturnType<typeof getStore>["dispatch"];

@markerikson Thanks so much, this helped me a lot! For anybody else getting here from google: Just now, when looking for the type for preloadedState I came across this very detailed answer at Type definitions for Redux (Toolkit) store with preloadedState which would make a great addition to https://redux-toolkit.js.org/tutorials/typescript or https://redux-toolkit.js.org/api/configureStore#full-example

Was this page helpful?
0 / 5 - 0 ratings

Related issues

FdezRomero picture FdezRomero  路  4Comments

emil14 picture emil14  路  3Comments

Darrekt picture Darrekt  路  3Comments

Izhaki picture Izhaki  路  3Comments

SoYoung210 picture SoYoung210  路  4Comments