import type { DynamicMiddlewareInstance, GetDispatch, GetState, MiddlewareApiConfig, TSHelpersExtractDispatchExtensions, } from '@reduxjs/toolkit' import { createDynamicMiddleware as cDM } from '@reduxjs/toolkit' import type { Context } from 'react' import type { ReactReduxContextValue } from 'react-redux' import { createDispatchHook, ReactReduxContext, useDispatch as useDefaultDispatch, } from 'react-redux' import type { Action, Dispatch, Middleware, UnknownAction } from 'redux' export type UseDispatchWithMiddlewareHook< Middlewares extends Middleware[] = [], State = any, DispatchType extends Dispatch = Dispatch, > = () => TSHelpersExtractDispatchExtensions & DispatchType export type CreateDispatchWithMiddlewareHook< State = any, DispatchType extends Dispatch = Dispatch, > = { < Middlewares extends [ Middleware, ...Middleware[], ], >( ...middlewares: Middlewares ): UseDispatchWithMiddlewareHook withTypes< MiddlewareConfig extends MiddlewareApiConfig, >(): CreateDispatchWithMiddlewareHook< GetState, GetDispatch > } type ActionFromDispatch> = DispatchType extends Dispatch ? Action : never type ReactDynamicMiddlewareInstance< State = any, DispatchType extends Dispatch = Dispatch, > = DynamicMiddlewareInstance & { createDispatchWithMiddlewareHookFactory: ( context?: Context > | null>, ) => CreateDispatchWithMiddlewareHook createDispatchWithMiddlewareHook: CreateDispatchWithMiddlewareHook< State, DispatchType > } export const createDynamicMiddleware = < State = any, DispatchType extends Dispatch = Dispatch, >(): ReactDynamicMiddlewareInstance => { const instance = cDM() const createDispatchWithMiddlewareHookFactory = ( // @ts-ignore context: Context > | null> = ReactReduxContext, ) => { const useDispatch = context === ReactReduxContext ? useDefaultDispatch : createDispatchHook(context) function createDispatchWithMiddlewareHook< Middlewares extends Middleware[], >(...middlewares: Middlewares) { instance.addMiddleware(...middlewares) return useDispatch } createDispatchWithMiddlewareHook.withTypes = () => createDispatchWithMiddlewareHook return createDispatchWithMiddlewareHook as CreateDispatchWithMiddlewareHook< State, DispatchType > } const createDispatchWithMiddlewareHook = createDispatchWithMiddlewareHookFactory() return { ...instance, createDispatchWithMiddlewareHookFactory, createDispatchWithMiddlewareHook, } }