Реализуйте на TypeScript класс по паттерну «Наблюдатель»: он хранит данные в объекте, позволяет подписываться и отписываться через subscribe/unsubscribe и уведомляет подписчиков при изменении данных через присваивание. Нужны getter и setter; начальное значение по умолчанию — пустой объект.

Наблюдателей удобно хранить в Set, уведомляя их в setter при присваивании нового объекта.

Короткий ответ

Что ответить на собеседовании

Наблюдателей удобно хранить в Set, уведомляя их в setter при присваивании нового объекта.

Подробный разбор

Ответ с пояснениями

Наблюдателей удобно хранить в Set, уведомляя их в setter при присваивании нового объекта.

Контракт ниже уведомляет при store.data = next, но не при вложенной мутации store.data.x = 1. Подписка не вызывает callback сразу; повторное присваивание той же ссылки пропускается.

type Data = Record<string, unknown>;
type Listener = (next: Data, previous: Data) => void;
class ObservableStore {
  private value: Data;
  private listeners = new Set<Listener>();
  constructor(initial: Data = {}) { this.value = initial; }
  get data(): Data { return this.value; }
  set data(next: Data) {
    if (Object.is(next, this.value)) return;
    const previous = this.value;
    this.value = next;
    const errors: unknown[] = [];
    for (const listener of [...this.listeners]) {
      try { listener(next, previous); }
      catch (error) { errors.push(error); }
    }
    if (errors.length) throw new AggregateError(errors, 'Ошибки наблюдателей');
  }
  subscribe(listener: Listener): () => void {
    this.listeners.add(listener);
    return () => this.unsubscribe(listener);
  }
  unsubscribe(listener: Listener): void { this.listeners.delete(listener); }
}

Используется ES2021 для AggregateError. Снимок подписчиков сохраняет состав текущего обхода; ошибки не мешают вызвать остальных. Для уведомлений о каждой вложенной записи потребуются отдельные методы обновления или Proxy.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее