import { ActionOf, ActionCreator } from './actionCreatorFactory'; import { Reducer } from 'redux'; export type Mapper = (state: State, action: ActionOf) => State; export interface MapperConfig { filter: ActionCreator; mapper: Mapper; } export interface AddMapper { addMapper: (config: MapperConfig) => CreateReducer; } export interface CreateReducer extends AddMapper { create: () => Reducer>; } export const reducerFactory = (initialState: State): AddMapper => { const allMappers: { [key: string]: Mapper } = {}; const addMapper = (config: MapperConfig): CreateReducer => { if (allMappers[config.filter.type]) { throw new Error(`There is already a mapper defined with the type ${config.filter.type}`); } allMappers[config.filter.type] = config.mapper; return instance; }; const create = (): Reducer> => (state: State = initialState, action: ActionOf): State => { const mapper = allMappers[action.type]; if (mapper) { return mapper(state, action); } return state; }; const instance: CreateReducer = { addMapper, create }; return instance; };