Ответ вслух Senior Условные и mapped-типы обновлено

Тип обработчиков из карты событий

Вопрос

Есть тип Events = { click: { x: number }; close: void }. Как вывести из него тип { onClick: (e: { x: number }) => void; onClose: (e: void) => void }?

Попробуйте сами

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

Показать ответ и разбор

Коротко

Беру mapped-тип по ключам карты и переименовываю ключи: type Handlers = { [K in keyof Events as on${Capitalize<string & K}]: (e: Events[K]) = void } . as с шаблонной строкой превращает click в onClick, а Events[K] подставляет тип полезной нагрузки. string & K нужен потому, что keyof в общем случае включает числа и…

Что должно прозвучать в ответе

  • Mapped-тип по `keyof Events`

  • Переназначение ключа через `as` и шаблонную строку `` `on${Capitalize<string & K>}` ``

  • Значение `(e: Events[K]) => void` через индексный доступ

  • `string & K` нужен, потому что `keyof` включает `number | symbol`

  • Один источник правды: добавил событие в карту, обработчик появился автоматически

Что могут спросить следом

  • Как сделать все обработчики необязательными?
  • Как обратно получить имя события из onClick?
  • Как типизировать emit(name, payload) на той же карте?

Разбор

Беру mapped-тип по ключам карты и переименовываю ключи: type Handlers = { [K in keyof Events as `on${Capitalize<string & K>}`]: (e: Events[K]) => void }. as с шаблонной строкой превращает click в onClick, а Events[K] подставляет тип полезной нагрузки. string & K нужен потому, что keyof в общем случае включает числа и символы, а Capitalize принимает только строки. Необязательными обработчики делаю добавлением ? после ключа. Обратная операция делается условным типом с infer: K extends `on${infer E}` ? Uncapitalize<E> : never. На той же карте типизируется и emit<K extends keyof Events>(name: K, payload: Events[K]). Плюс подхода в том, что карта событий одна, и всё остальное выводится из неё.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.