TypeScript в команде: code style, конвенции и никакого хаоса

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

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

Начать курс

Почему «работает» — это не про команду?

Представьте: вы открываете чужой PR, а там any на каждом шагу, переменные названы a, b, c, и всё отформатировано так, будто код писал кот, гуляющий по клавиатуре. Знакомо? В одиночку такой код можно и пережить. Но в команде это — путь к конфликтам, багам и бессонным ночам на код-ревью.

Сегодня поговорим о том, как сделать TypeScript в команде не просто инструментом, а надёжным фундаментом. Мы разберём code style и конвенции, которые спасут ваши нервы и ускорят разработку. Без занудства, с живыми примерами.

1. Строгая типизация: ваш первый друг

TypeScript — это про типы. Но многие команды используют его как «TypeScript-lite», оставляя any везде, где лень подумать. Это убивает всю магию. Первая конвенция: запретить any.

Плохо:

function fetchData(url: string): any {
    // ...
}

Хорошо:

interface ApiResponse {
    id: number;
    name: string;
    isActive: boolean;
}

function fetchData(url: string): Promise<ApiResponse> {
    // ...
}

Когда каждый разработчик явно описывает, что он возвращает и принимает, код становится самодокументируемым. Вы больше не гадаете: «Этот data — строка или объект?». Типы говорят сами за себя.

2. ESLint + Prettier: настройка, которая не обсуждается

Если в вашей команде до сих пор нет единого линтера и форматтера, остановитесь и настройте их прямо сейчас. ESLint ловит логические ошибки и нарушения code style, а Prettier делает код единообразным.

Базовая конфигурация ESLint для TypeScript:

{
  "parser": "@typescript-eslint/parser",
  "plugins": ["@typescript-eslint"],
  "extends": [
    "eslint:recommended",
    "plugin:@typescript-eslint/recommended",
    "prettier" // обязательно в конце
  ],
  "rules": {
    "@typescript-eslint/no-explicit-any": "error",
    "@typescript-eslint/explicit-function-return-type": "warn",
    "no-console": "warn"
  }
}

Добавьте Prettier с простыми правилами: табы вместо пробелов (или наоборот, но единообразно), одинарные кавычки, точка с запятой в конце. И включите formatOnSave в IDE. Это спасёт от бесконечных споров про отступы.

3. Именование: говорите на одном языке

Конвенции именования — это как правила дорожного движения. Без них — хаос. В TypeScript приняты такие соглашения:

  • camelCase для переменных, функций, методов: getUserData(), userName
  • PascalCase для классов, интерфейсов, типов: UserProfile, ApiResponse
  • UPPER_SNAKE_CASE для констант, известных на момент компиляции: MAX_RETRY_COUNT, DEFAULT_TIMEOUT
  • Префикс I для интерфейсов — спорный, но многие команды его используют: IUser. Решите это на старте.

Пример плохого нейминга:

const data = { n: 'Alex', a: 30 }; // что такое n и a?

Хорошо:

const userProfile = { name: 'Alex', age: 30 };

4. Структура проекта: не прячьте всё в один файл

Когда проект разрастается, отсутствие структуры — главный враг. Договоритесь о папках заранее. Вот популярный вариант для TypeScript-проекта:

  • src/ — исходный код
  • src/components/ — UI-компоненты (если React)
  • src/utils/ — утилитарные функции
  • src/types/ — глобальные типы и интерфейсы
  • src/services/ — работа с API
  • src/hooks/ — кастомные хуки (если React)

Каждый модуль — отдельная папка с index.ts для экспорта. Это упрощает рефакторинг и тестирование.

5. Комментарии: меньше, но метко

Хороший code style — это когда комментарии не нужны, потому что код говорит сам за себя. Но иногда без них не обойтись. Конвенция: пишите комментарии только там, где код сложен или неочевиден. Не комментируйте очевидное:

// Плохо: бессмысленный комментарий
// Прибавляем 1 к счетчику
counter++;

Лучше так:

// Хорошо: объясняем бизнес-логику
// Пропускаем первого пользователя, так как это тестовый аккаунт
const users = await getUsers();
const filteredUsers = users.slice(1);

Для документации функций используйте JSDoc:

/**
 * Получает список активных пользователей.
 * @param page - номер страницы для пагинации
 * @returns массив пользователей
 */
async function getActiveUsers(page: number): Promise<User[]> {
    // ...
}

6. Код-ревью: конвенции в действии

Без code style и конвенций код-ревью превращается в бесконечное «а давай переименуем», «а почему тут any?». Когда у вас есть единый стандарт, ревьюер проверяет логику, а не форматирование. Вот чек-лист для ревью TypeScript-кода:

  • Нет ли any там, где можно указать конкретный тип?
  • Соблюдены ли конвенции именования?
  • Есть ли лишние комментарии или их не хватает?
  • Не нарушена ли структура проекта?
  • Проходит ли код ESLint и Prettier?

Совет: добавьте в CI пайплайн проверку линтера. Если код не проходит — PR не мержится. Жестко, но эффективно.

7. Утилиты и общие типы: DRY для TypeScript

В любой команде есть повторяющиеся паттерны. Выносите их в общие типы и утилиты. Это уменьшает дублирование и ошибки.

// Общий тип для ответа API
export interface ApiResponse<T> {
    data: T;
    success: boolean;
    error?: string;
}

// Утилита для обработки ошибок
export function handleApiError(error: unknown): never {
    if (error instanceof Error) {                

Блоги

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