Skip to content

Circular type reference in custom middleware when ReturnType<typeof store.getState> #4267

@nelsonni

Description

@nelsonni

What docs page needs to be fixed?

What is the problem?

When using TypeScript with RTK and adding types to a custom middleware following from https://redux.js.org/usage/usage-with-typescript#type-checking-middleware, for example:

import { Middleware } from 'redux'; import { RootState } from '../store'; export const simpleMiddleware: Middleware<unknown, RootState> = api => next => action => { const result = next(action); if (action.type === 'cards/fetchById') { console.group(action.type); console.log(`dispatching`, action); console.log('next state', api.getState()); console.groupEnd(); } return result; }

And setting the RootState type following https://redux.js.org/usage/usage-with-typescript#define-root-state-and-dispatch-types, i.e.:

export type RootState = ReturnType<typeof store.getState>

Then the following circular type reference error is thrown:

'simpleMiddleware' is referenced directly or indirectly in its own type annotation. ts(2502)

This issue occurs because the middleware needs the RootState type, but that type isn't defined and available until the store is created, and the store needs the middleware in order to do that.

What should be changed to fix the problem?

Per @markerikson on Reactiflux Discord, this can be fixed by switching the definition of RootState to be:

const rootReducer = combineReducers({ ... }); type RootState = ReturnType<typeof rootReducer>;

This information should be noted under the Type Checking Middleware section.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions