Строгий TypeScript на клиентских проектах: считаем, окупается ли

Строгий режим замедляет старт и экономит на поддержке. Сравниваем два похожих проекта — со строгими типами и без — по числу правок после сдачи.

СФронтенд

Строгий режим TypeScript — это лишние часы в начале проекта и меньше сюрпризов потом. Вопрос в том, окупается ли обмен на коротких проектах, где половина сайтов сдаётся за месяц.

Что включает строгий режим

Флаг strict объединяет несколько проверок. Главные из них две: запрет неявного any и строгая проверка на null и undefined.

{
  "compilerOptions": {
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "exactOptionalPropertyTypes": true
  }
}

Отдельно стоит noUncheckedIndexedAccess: он заставляет проверять результат обращения по индексу. Именно эта проверка ловит самый частый рантайм-баг — обращение к элементу пустого массива.

Сравнение двух проектов

Два корпоративных сайта похожего объёма, сданы с разницей в четыре месяца, разные команды внутри студии. Первый — без строгого режима, второй — со строгим и дополнительными флагами.

  • Время разработки: 19 дней против 23 — строгий режим добавил около 20%.
  • Правки по багам за три месяца после сдачи: 14 против 4.
  • Из них связанных с отсутствующими данными: 9 против 0.
  • Суммарно время на поддержку: 21 час против 6.

На дистанции в квартал строгий режим окупился примерно вдвое. На проекте, который сдали и забыли, он был бы чистым убытком — но таких проектов у нас почти нет: клиенты возвращаются с доработками.

Где строгость мешает

Данные из внешних источников

Ответ чужого API типизировать бессмысленно: реальность всё равно окажется другой. Мы валидируем такие данные на границе и внутрь пускаем уже проверенный объект.

import { z } from 'zod'

const OrderSchema = z.object({
  id: z.string(),
  total: z.number(),
  items: z.array(z.object({ sku: z.string(), qty: z.number() })),
})

// Дальше по коду тип известен и гарантирован
export function parseOrder(raw: unknown) {
  return OrderSchema.parse(raw)
}

Быстрые прототипы

Если задача — показать клиенту идею за два дня, строгие типы только мешают. Прототип живёт в отдельной ветке и в продакшен не едет.

Компромисс, который работает

Включаем строгий режим на новом коде и оставляем послабления для старого: в tsconfig можно указать разные настройки для разных папок. Так не приходится останавливать разработку ради миграции.

Как переводить существующий проект

  1. Включаем strict и смотрим количество ошибок — обычно их сотни.
  2. Не чиним всё сразу: добавляем // @ts-expect-error с комментарием и датой.
  3. Каждую неделю разбираем часть помеченных мест.
  4. Запрещаем добавлять новые подавления через правило линтера.

Какие настройки дают эффект, а какие только шум

Строгий режим — это не одна галочка, а набор проверок, и они очень разные по отдаче. Главная — strictNullChecks: именно она ловит обращения к тому, чего может не быть, а это самый частый источник падений в браузере.

Дальше по полезности идёт noUncheckedIndexedAccess: обращение к элементу массива по индексу перестаёт считаться безопасным. Настройка раздражает первые дни и окупается на любом коде, который перебирает данные с сервера.

А вот noImplicitAny на существующем проекте лучше включать последним. Он даёт сотни ошибок сразу, и команда начинает расставлять any вместо типов — то есть делать ровно противоположное задуманному. Мы включаем его после того, как остальное уже зелёное.

Где типы не окупаются

Короткие лендинги (посадочная страница) с двумя формами. Проект живёт месяц, кода мало, читать его повторно никто не будет — настройка окружения займёт больше времени, чем сэкономит.

Прототипы и эксперименты. Там ценна скорость проверки гипотезы, а типы заставляют оформлять то, что завтра выкинут. Мы прямо разделяем: прототип пишется свободно, а в продукт переносится уже с типами.

Частые вопросы

Сколько стоит перевод существующего проекта?

По нашему опыту около 8–12% от объёма кодовой базы в человеко-часах, если переводить постепенно, файл за файлом. Разово и целиком — дороже и рискованнее: слишком много изменений в одном релизе (выпуск).

Заменяет ли TypeScript тесты?

Нет. Типы проверяют форму данных, тесты — поведение. Правильно посчитанная скидка неправильной формулой пройдёт проверку типов и не пройдёт тест. Одно без другого работает хуже.

Через два-три месяца проект оказывается полностью строгим, и никто не тратил на это отдельный спринт.

4 мин чтения
ЕГЕРПРО

ЕГЕРПРО

Команда студии ЕГЕРПРО: разработчики, дизайнеры, SEO-специалисты и специалисты по технологиям искусственного интеллекта. Создаём сайты и веб-сервисы, внедряем решения на основе искусственного интеллекта и автоматизацию, работаем над скоростью и продвижением сайтов. Пишем только о технологиях и подходах, которые проверили на реальных клиентских проектах.

Нужен сайт, который так же разобран по деталям?

Оценим задачу бесплатно и пришлём смету со сроками.

Читайте также

Похожие статьи

Сайт в разработке информация наполняется. Часть разделов может быть неполной.