Home > other >  Export Redux store state type when configuring it asynchronously
Export Redux store state type when configuring it asynchronously

Time:06-03

everyone!

I'm trying to configure Redux store with preloaded state, which I can obtain only asynchronously using TypeScript.

Question

Am I able to lazy infer state and dispatch types like it's described in the official doc, whereas I'm receiving store instance only inside Promise callback when preloadedState was calculated?

Here is a bunch of code which hopefully would clarify what I meant to do:

const getPreloadedState = async (): Promise<RootState> => { // Need RootState type on that very stage already
    const restoredSession = await Session.restore()
    const preloadedState: RootState = {
        session: {
            sessionKey: restoredSession.sessionKey,
            expiresIn: restoredSession.expiresIn
        }
    }
    return Promise.resolve(preloadedState)
}

export const configureStoreAsync = async (): Promise<EnhancedStore> => {
    const preloadedState = await getPreloadedState()
    const store = configureStore({
        reducer: rootReducer,
        preloadedState: preloadedState
    })

    //  Unable to export this types here when state is ready. 
    //  (getting "Modifiers cannot appear here" error)
    //  export type RootState = ReturnType<typeof store.getState>
    //  export type AppDispatch = typeof store.dispatch

    return Promise.resolve(store)
}
Possible solution

Here is what I come up with:

//  Generate dummy store to calculate typeof state
const store = configureStore({reducer: rootReducer})    
export type RootState = ReturnType<typeof store.getState>
export type AppDispatch = typeof store.dispatch

but I'm very much interested on the opinions of more knowledgeable developers in the field..

 
Thanks in advance!

CodePudding user response:

// remove the return type from this function or you will actually erase imporant type information
export const configureStoreAsync = async () => {
    const preloadedState = await getPreloadedState()
    const store = configureStore({
        reducer: rootReducer,
        preloadedState: preloadedState
    })
    
    // the Promise.resolve is unneccessary, that is implied by using an `async` function

    return store
}


type Store = Awaited<ReturnType<configureStoreAsync>>
export type RootState = ReturnType<Store['getState']>
export type AppDispatch = Store['dispatch']
  • Related