Ответ вслух Middle Утилитарные типы спрашивают часто обновлено

Как устроены Pick и Omit

Вопрос

Напишите Pick и Omit своими словами и объясните, как они работают.

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

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

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

Коротко

Pick это mapped-тип: type MyPick<T, K extends keyof T = { [P in K]: T[P] }. Он проходит по переданным ключам и для каждого берёт тип поля из исходника.

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

  • `Pick<T, K extends keyof T> = { [P in K]: T[P] }`: mapped-тип по выбранным ключам

  • Ограничение `K extends keyof T` запрещает несуществующие ключи

  • `Omit<T, K> = Pick<T, Exclude<keyof T, K>>`: оставить все ключи, кроме указанных

  • У встроенного `Omit` ключ не ограничен `keyof T`, поэтому опечатка проходит молча

  • Оба не распределяются по объединению и работают на верхнем уровне

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

  • Как сделать Omit строгим?
  • Как написать распределённый Omit для объединения?
  • Почему Pick сохраняет readonly и ??

Разбор

Pick это mapped-тип: type MyPick<T, K extends keyof T> = { [P in K]: T[P] }. Он проходит по переданным ключам и для каждого берёт тип поля из исходника. Ограничение K extends keyof T не даёт передать ключ, которого нет. Omit выражается через Pick: берём все ключи keyof T, через Exclude убираем лишние и передаём остаток в Pick. У встроенного Omit ограничение K extends keyof any, поэтому Omit<User, 'opechatka'> компилируется; если это мешает, делаю обёртку с K extends keyof T. Модификаторы readonly и ? сохраняются, потому что mapped-тип по ключам T гомоморфный. И важно: на объединении Omit склеивает варианты, для дискриминированных объединений нужен распределённый вариант через условный тип.

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

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