ts-09-typed-store
1.000
Proposed solution
```ts
export function createStore<S, A>(
reducer: (state: S, action: A) => S,
initial: S,
): {
getState(): S;
dispatch(action: A): void;
subscribe(fn: () => void): () => void;
} {
let state = initial;
const subscribers = new Set<() => void>();
return {
getState() {
return state;
},
dispatch(action: A) {
state = reducer(state, action);
subscribers.forEach(fn => fn());
},
subscribe(fn: () => void) {
subscribers.add(fn);
return () => {
subscribers.delete(fn);
};
}
};
}
```Test output (stdout)
TAP version 13 # Subtest: starts at the initial state ok 1 - starts at the initial state --- duration_ms: 0.374752 type: 'test' ... # Subtest: dispatch updates state via the reducer ok 2 - dispatch updates state via the reducer --- duration_ms: 0.437353 type: 'test' ... # Subtest: subscribers fire on every dispatch ok 3 - subscribers fire on every dispatch --- duration_ms: 0.0774 type: 'test' ... # Subtest: multiple subscribers all fire ok 4 - multiple subscribers all fire --- duration_ms: 0.049241 type: 'test' ... # Subtest: unsubscribe stops notifications ok 5 - unsubscribe stops notifications --- duration_ms: 0.0554 type: 'test' ... # Subtest: unsubscribing twice is harmless ok 6 - unsubscribing twice is harmless --- duration_ms: 0.078191 type: 'test' ... # Subtest: subscriber sees the updated state when notified ok 7 - subscriber sees the updated state when notified --- duration_ms: 0.318992 type: 'test' ... # Subtest: works with an object state shape ok 8 - works with an object state shape --- duration_ms: 0.08082 type: 'test' ... 1..8 # tests 8 # suites 0 # pass 8 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 81.96153
System prompt
You are an expert programmer. Solve the task exactly as specified. Output your solution as fenced code blocks using the required file name(s) and the exact function/type signatures requested. Prefer correctness; do not include prose outside code unless asked.