Код Senior Классы и интерфейсы обновлено

Типизированный стор с подписками на срезы

Условие

Напиши класс Store<S extends object>:

  • getState(): Readonly<S>;
  • setState(patch: Partial<S> | ((s: Readonly<S>) => Partial<S>)): void: новый объект состояния, старый не мутировать; слушатели вызываются, только если хоть одно поле изменилось (Object.is);
  • select<T>(selector: (s: Readonly<S>) => T, fn: (value: T, prev: T) => void): () => void: вызывать fn только при изменении выбранного значения (Object.is), вернуть отписку.

run(steps) в заготовке выполняет шаги и возвращает лог уведомлений.

Примеры

run([{"cart":2}, {"incCart":true}]) // ["cart 0->2", "cart 2->3", "initial untouched true"]
run([{"user":"ann"}, {"user":"bob"}, {"user":null}]) // ["logged true", "logged false", "initial untouched true"]
run([{"cart":0}]) // ["initial untouched true"]

Как подойти

Подсказки: 2
  1. Функциональный апдейт отличай через typeof patch === "function".
  2. Селектор хранит предыдущее выбранное значение в замыкании.

Решите в тренажёре

Редактор с автотестами прямо в браузере. Можно решить спокойно, вслух или под таймером, как на собесе.