/* eslint-disable @typescript-eslint/consistent-indexed-object-style */ /* A number of these types have been used exactly or adapted from MIT licensed @reduxjs/toolkit */ export type Action = { type: T } export interface UnknownAction extends Action { [key: string]: unknown } export interface AnyAction extends Action { [key: string]: any } export type CaseReducer< S = any, A extends Action = AnyAction, R = S | undefined, > = (state: S, action: A) => R export type PayloadAction

= { payload: P type: T } type SliceCaseReducer = Record< string, CaseReducer> > export type CreateReducerParams = { initialState: TState reducers: SliceCaseReducer } export type CreateReducerReturn = { initialState: TState reducer: CaseReducer, TState> } export function createReducer< TState, TParams extends CreateReducerParams = CreateReducerParams, >({ initialState, reducers }: TParams): CreateReducerReturn { const actions = new Map(Object.entries(reducers)) const reducer = (state: TState, action: PayloadAction) => { if (actions.has(action.type)) { const handler = actions.get(action.type) if (handler) { const newState = handler(state, action) if (newState !== undefined && newState !== state) { return newState } } } return state } return { initialState, reducer, } }