I've been integrating redux-toolkits createListenerMiddleware recently but I'm kinda stuck at the moment. I'm trying to type some of my "listener entries" but can't seem to manage it. Intelli-sense just doesn't make sense to me and I can't find any examples in the docs or online for that matter. The goal is to have the listenerApi
argument typed so I can use the getState()
function without having to do any typecasting.
Is there any easy way to achieve this?
Any help would be greatly appreciated.
listenerMiddleware.startListening({
actionCreator: toggleSomething, // Action generator from reducer createSlice
effect: async (
action: AnyAction,
listenerApi: ListenerEffectAPI<AppState, Dispatch> // Trying to type this in some way :[
): Promise<void> => {
const state = (await listenerApi.getState()) as AppState; // TODO: type this better
},
});
CodePudding user response:
startListening
is designed to infer the correct TS types as much as possible.
Assuming that your action creator ( toggleSomething
) is typed correctly (which it should be if you're following our RTK TS usage guidelines), startListening
will correctly infer the type of action
inside of the effect
callback.
That leaves the type of getState
. RTK and TS can't know that ahead of time, because the middleware gets added to the store. That's why we we designed the API to let you create a "pre-typed" version of startListening
that has the correct state type applied, as shown in the API docs here:
Example:
// listenerMiddleware.ts
import { createListenerMiddleware, addListener } from '@reduxjs/toolkit'
import type { TypedStartListening, TypedAddListener } from '@reduxjs/toolkit'
import type { RootState, AppDispatch } from './store'
export const listenerMiddleware = createListenerMiddleware()
export type AppStartListening = TypedStartListening<RootState, AppDispatch>
export const startAppListening =
listenerMiddleware.startListening as AppStartListening
export const addAppListener = addListener as TypedAddListener<
RootState,
AppDispatch
>