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

Тип для частичного обновления

Вопрос

Как типизировать функцию updateUser(id, patch), где patch может содержать любые поля пользователя, кроме id и createdAt?

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

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

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

Коротко

Держу один источник правды: тип User. Для изменения беру Partial<Omit<User, 'id' 'createdAt': убираю поля, которые менять нельзя, и делаю остальные необязательными.

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

  • Базовый тип `User` один, остальные выводятся из него утилитами

  • `Partial<Omit<User, 'id' | 'createdAt'>>` для patch

  • Отдельно `id: User['id']`, чтобы тип id менялся вместе с моделью

  • Опасность `Partial`: можно передать пустой объект, при необходимости требовать хотя бы одно поле

  • Нюанс: `Partial` разрешает явный `undefined`, флаг `exactOptionalPropertyTypes` это запрещает

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

  • Как запретить пустой patch?
  • Чем плохо описать UpdateUserDto вручную?
  • Как быть с вложенными объектами?

Разбор

Держу один источник правды: тип User. Для изменения беру Partial<Omit<User, 'id' | 'createdAt'>>: убираю поля, которые менять нельзя, и делаю остальные необязательными. Параметр id типизирую как User['id'], чтобы при смене id на строку всё обновилось само. Если описать DTO вручную, типы со временем разъедутся. Нюансы: Partial поверхностный, вложенный address придётся передавать целиком или писать DeepPartial. Пустой объект тоже проходит; если это ошибка, можно потребовать хотя бы одно поле утилитой с объединением по ключам. И Partial допускает явный { name: undefined }, что для PATCH может значить «стереть». Если это важно, включаю exactOptionalPropertyTypes.

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

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