Code review в TypeScript: что проверять и как давать обратную связь

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Code review в TypeScript: что проверять и как давать обратную связь на практике

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

1. Типы и аннотации: избегаем `any` и используем строгость

Первое, что бросается в глаза на ревью TypeScript-кода — это типы. TypeScript создан для того, чтобы ловить ошибки на этапе компиляции, поэтому any — это красный флаг.

Что проверять:

  • Наличие any. Каждое any должно быть оправдано. Если это миграция с JS — ок, но в новом коде — нет.
  • Корректность типов. Не используйте string там, где нужен enum или union type.
  • Излишняя типизация. TypeScript умеет выводить типы. Не пишите const x: number = 5 — пишите const x = 5.
  • Строгие настройки. Проверьте, что в tsconfig.json включены strict: true, noImplicitAny, strictNullChecks.

Пример плохого кода:

function processData(data: any) {
  return data.name.toLowerCase();
}

Как исправить:

interface User {
  name: string;
}

function processData(data: User): string {
  return data.name.toLowerCase();
}

Как дать обратную связь:

Вместо «Ты используешь any, это плохо» скажите: «Здесь any отключает проверку типов. Давай опишем интерфейс User — это повысит безопасность и читаемость кода».

2. Работа с null и undefined: strictNullChecks спасает жизнь

Ошибки Cannot read property of undefined — классика. TypeScript с strictNullChecks помогает их избежать, но только если разработчик правильно обрабатывает nullable-значения.

Что проверять:

  • Проверка на null/undefined перед обращением к свойствам.
  • Использование optional chaining (?.) — это современно и безопасно.
  • Оператор ! (non-null assertion) — используйте только если на 100% уверены, что значение не null. Лучше заменить на явную проверку.
  • Правильное использование ?? (nullish coalescing) вместо || для значений по умолчанию.

Пример плохого кода:

function getCity(user: User | null): string {
  return user!.address!.city; // Опасно!
}

Как исправить:

function getCity(user: User | null): string {
  return user?.address?.city ?? 'Unknown';
}

Как дать обратную связь:

«Использование ! здесь рискованно — если user окажется null, упадёт ошибка. Давай заменим на ?. и ?? — это безопасно и читаемо».

3. Дженерики и утилитарные типы: не усложняйте без нужды

Дженерики — мощная фича, но их легко переусложнить. Ревьюер должен следить за балансом между гибкостью и читаемостью.

Что проверять:

  • Избыточная сложность. Если дженерик используется всего один раз, возможно, он не нужен.
  • Правильное использование extends — ограничивайте дженерики, чтобы они не принимали всё подряд.
  • Утилитарные типы (Partial, Pick, Omit, Record) — их использование упрощает код.
  • Типы возвращаемых значений — функция с дженериком должна возвращать что-то осмысленное, а не any.

Пример плохого кода:

function getProperty<T, K>(obj: T, key: K) {
  return (obj as any)[key];
}

Как исправить:

function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

Как дать обратную связь:

«Здесь дженерик K не ограничен — можно передать любое значение, и TypeScript не проверит ключ. Добавь extends keyof T — это даст автодополнение и безопасность».

4. Async/await и обработка ошибок: не забывайте про reject

Асинхронный код в TypeScript — частая причина трудноуловимых багов. Особенно если разработчик не обрабатывает ошибки или забывает про типы промисов.

Что проверять:

  • Возвращаемый тип промиса — функция должна возвращать Promise<T>, а не Promise<any>.
  • Обработка ошибок — есть ли try/catch? Если нет, то как ошибка будет обработана выше?
  • Параллельные запросы — используйте Promise.all или Promise.allSettled, а не последовательные await.
  • Неиспользуемые промисы — если вы не ждёте результат, убедитесь, что это намеренно.

Пример плохого кода:

async function fetchUsers() {
  const response = await fetch('/api/users');
  return response.json(); // Тип - any
}

Как исправить:

interface User {                

Блоги

Рекомендаций по книгам