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 allMapperConfigs: Array> = []; const addMapper = (config: MapperConfig): CreateReducer => { if (allMapperConfigs.some(c => c.filter.type === config.filter.type)) { throw new Error(`There is already a Mappers defined with the type ${config.filter.type}`); } allMapperConfigs.push(config); return instance; }; const create = (): Reducer> => (state: State = initialState, action: ActionOf): State => { const mapperConfig = allMapperConfigs.filter(config => config.filter.type === action.type)[0]; if (mapperConfig) { return mapperConfig.mapper(state, action); } return state; }; const instance: CreateReducer = { addMapper, create }; return instance; };