Ответ вслух Senior Объединения и сужение обновлено

Типы на границах системы

Вопрос

Как вы строите типобезопасность на границах сервиса: входящие HTTP-запросы, ответы внешних API, данные из БД и JSON.parse?

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

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

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

Коротко

Типы TypeScript исчезают в рантайме, поэтому всё, что пересекает границу процесса, это unknown, пока не доказано обратное. response.json() as User не проверка, а обещание, и при изменении внешнего API ошибка всплывёт далеко от места причины.

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

  • Всё внешнее приходит как `unknown`, а не `any` и не `as T`

  • Рантайм-валидация схемой (zod, valibot, ajv) и вывод типа из схемы, один источник правды

  • Type guards и assertion functions для точечных проверок

  • Branded типы для проверенных значений: `Email`, `UserId`, `Kopecks`

  • Внутри системы данные уже доверенные, проверок не дублируем

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

  • Чем опасен as на ответе fetch?
  • Где хранить схемы, чтобы фронт и бэк не разошлись?
  • Как быть с данными из БД: проверять или доверять ORM?

Разбор

Типы TypeScript исчезают в рантайме, поэтому всё, что пересекает границу процесса, это unknown, пока не доказано обратное. response.json() as User не проверка, а обещание, и при изменении внешнего API ошибка всплывёт далеко от места причины. Поэтому на входе стоит схема: zod или valibot для запросов и ответов внешних API, а тип выводится из схемы, чтобы они не расходились. Для узких мест пишу type guard или assertion function. Проверенные значения можно пометить branded-типом: функция, принимающая Email, уже не получит непроверенную строку. Внутри доменного слоя проверки не дублирую, граница одна. Данные из БД обычно типизирует ORM (Prisma, Drizzle), но JSON-колонки и сырые запросы снова проходят через схему.

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

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