Created
March 28, 2017 22:16
-
-
Save jakobz/47cfa3c71a676811c3fe261b4327478b to your computer and use it in GitHub Desktop.
Tiny Typed Redux-like state manager in typescript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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