export interface SubscriptionCallback < T > { ( item ) : void ; } export interface Store < T extends object > { subscribeToItem < K extends keyof T > ( key , callback ) : void ; unsubscribeFromItem < K extends keyof T > ( key , callback ) : void ; updateItem < K extends keyof T > ( key , item ) : void ; getItem < K extends keyof T > ( key ) : T [ K ] ; } export function createStore < T extends object > ( initialState = { } as T ) { let state = initialState ; const listeners = { } as { [ x in keyof T ] : Array < ( v : any ) => void > ; } ; return { subscribeToItem ( key , callback ) { listeners [ key ] = listeners [ key ] || [ ] ; listeners [ key ] ! . push ( callback ) ; } , unsubscribeFromItem ( key , callback ) { const listener = listeners [ key ] ; if ( listener ) { listeners [ key ] = listener . filter ( ( currentListener ) => currentListener !== callback ) ; } } , updateItem ( key , item ) { state = { ... state , [ key ] : item , } ; const listener = listeners [ key ] ; if ( listener ) { listener . forEach ( ( currentListener ) => currentListener ( state [ key ] ) ) ; } } , getItem ( key ) { return state [ key ] ; } , } ; }