Skip to content

Instantly share code, notes, and snippets.

@jakobz
Created March 28, 2017 22:16
Show Gist options
  • Save jakobz/47cfa3c71a676811c3fe261b4327478b to your computer and use it in GitHub Desktop.
Save jakobz/47cfa3c71a676811c3fe261b4327478b to your computer and use it in GitHub Desktop.
Tiny Typed Redux-like state manager in typescript
// Redux mini
type Reducer<TPayload, TState> = (params: TPayload) => (state: TState) => TState;
type Action<TPayload> = { name: string, payload: TPayload };
type ActionFactory<TPayload> = (payload: TPayload) => Action<TPayload>;
type ActionDispatcher<TPayload> = (payload: TPayload) => void;
type ReducersSet<TActions, TState> = { [P in keyof TActions]: Reducer<TActions[P], TState> }
type ActionFactorySet<TActions> = { [TActionName in keyof TActions]: ActionFactory<TActions[TActionName]> }
type ActionDispatcherSet<TActions> = { [TActionName in keyof TActions]: ActionDispatcher<TActions[TActionName]> }
export function createStore<TState, TActions>(initialState: TState, reducers: ReducersSet<TActions, TState>) : ActionDispatcherSet<TActions> {
let state = initialState;
function dispatch(action) {
let reducer = reducers[action.name];
console.log(`Dispatching ${action.name}. Payload: ${JSON.stringify(action.payload)}`);
let newState = reducer(action.payload)(state);
console.log(`State changed: ${JSON.stringify(state)} => ${JSON.stringify(newState)}`);
state = newState;
}
function wrapDispatch<TPayload>(name: string) {
return function(payload: TPayload) {
dispatch({ name, payload });
}
}
var store: any = {};
Object.keys(reducers).map(name => store[name] = wrapDispatch(name))
return store;
}
// Implementation
export interface AppState {
stringVal: string;
intVal: number;
}
const initialState: AppState = {
stringVal: 'initial value',
intVal: 100500
}
export const reducers = {
resetVal: ({}) => state => ({ ...state, stringVal: '' }),
setVal: (stringVal: string) => state => ({ ...state, stringVal })
}
export var store = createStore(initialState, reducers);
store.resetVal({});
store.setVal("Test");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment