This library is a framework-agnostic attempt to create typed reducers with Typescript following a class-based approach. Due to this, it plays particularly nicely with @ngrx.
npm i typed-reducer --save
import { createReducer, Action } from 'typed-reducer';
const ACTION_TYPE = 'ACTION_TYPE';
// define an action
class MyAction {
public type = ACTION_TYPE;
constructor(public payload: string) {}
}
// create a class, each method is a branch of what we would normally do with a switch statement
export class Reducer {
@Action
public someMethod(state: string[], action: MyAction): State {
return [ ...state, action.payload];
}
}
export const reducer = createReducer(Reducer);import { createReducer, Action } from 'typed-reducer';
import { CreateTodoAction, MarkTodoDoneAction, ArchiveTodoAction } from './todo.actions';
import { createTodo } from './create-todo';
export class TodoReducer {
@Action
public createTodo(state: Todo[], action: CreateTodoAction): Todo[] {
return [ ...state, createTodo(action.payload)];
}
@Action
public markDone(state: Todo[], action: MarkTodoDoneAction): Todo[] {
return state.map(todo => {
return todo.id === action.payload ? { ...todo, done: true } : todo
});
}
@Action
public archiveTodo(state: Todo[], action: ArchiveTodoAction): Todo[] {
return state.filter(todo => todo.id !== action.payload);
}
}
export const reducer = createReducer(TodoReducer);import { reducer } from './todos.reducer.ts';
// initial state of the store's tree
const initialState = {
todos: []
};
// create your store tree
export const rootReducer = (
state: AppState = initialState,
action: Action
) => {
return {
todos: reducer(state.todos, action),
// here go your other reducers
};
};
// export a factory to be AOT compliant
export function reducerFactory() {
return rootReducer;
};
// let's pass the factory function to StoreModule
@NgModule({
// module's configuration ...
imports: [
StoreModule.forRoot(undefined, { reducerFactory })
]
})
export class AppModule { }In order to prevent errors related to mutating the state, you can pass the option freeze, so that the state will be frozen using Object.freeze. Do this only in dev mode.
const options = { freeze: true };
export const todos = createReducer(TodoReducer, options);It is possible to log every action by setting the property log to true. This has been inspired by ngrx-store-logger. Do this only in dev mode.
const options = { log: true };
export const todos = createReducer(TodoReducer, options);