Clean Code на TypeScript: принципы и примеры для разработчиков

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

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

Начать курс

Clean Code на TypeScript: принципы и примеры

В современной веб-разработке TypeScript стал стандартом де-факто для создания крупных и надёжных приложений. Однако сам по себе TypeScript не гарантирует качества кода. Чтобы проект оставался гибким, понятным и легко поддерживаемым, необходимо следовать принципам Clean Code. В этой статье мы разберём основные концепции чистого кода на TypeScript с наглядными примерами. Вы узнаете, как писать код, который будет радовать не только компилятор, но и ваших коллег.

Почему Clean Code важен для TypeScript?

TypeScript добавляет в JavaScript статическую типизацию, что уже помогает избежать множества ошибок. Но типы — это лишь инструмент. Без продуманной архитектуры и читаемого стиля код всё равно превращается в «спагетти». Clean Code — это философия, которая делает код:

  • Читаемым — любой разработчик быстро поймёт логику.
  • Поддерживаемым — изменения в одном месте не ломают всё приложение.
  • Масштабируемым — добавление новых функций не требует переписывания половины проекта.

Применение этих принципов в TypeScript позволяет использовать мощь системы типов на полную катушку, создавая самодокументируемый код.

Принцип 1: Именование переменных и функций

Хорошее имя — половина успеха. Имя должно отвечать на вопросы «что?» и «зачем?», а не «как?». Избегайте однобуквенных переменных и сокращений, которые понятны только вам.

Плохой пример:

// Что такое d? А y?
const d = new Date();
const y = d.getFullYear();
const fn = (a: number, b: number) => a + b;

Хороший пример:

const currentDate = new Date();
const currentYear = currentDate.getFullYear();

const sum = (firstNumber: number, secondNumber: number): number => {
    return firstNumber + secondNumber;
};

Совет: Используйте осмысленные имена. Для булевых значений применяйте префиксы is, has, should. Например: isActive, hasPermission.

Принцип 2: Функции должны быть маленькими и делать одну вещь

Функция не должна отвечать за несколько задач одновременно. Если функция делает больше одного действия — её пора разбивать. Это повышает переиспользуемость и упрощает тестирование.

Плохой пример (функция делает всё сразу):

function processUserData(user: any) {
    // Валидация
    if (!user.email || !user.name) {
        throw new Error('Invalid user');
    }
    // Форматирование
    const formattedUser = {
        fullName: user.name.toUpperCase(),
        emailDomain: user.email.split('@')[1]
    };
    // Сохранение в БД
    database.save(formattedUser);
    // Отправка письма
    emailService.sendWelcomeEmail(formattedUser);
}

Хороший пример (разделение ответственности):

function validateUser(user: User): void {
    if (!user.email || !user.name) {
        throw new Error('Invalid user data');
    }
}

function formatUser(user: User): FormattedUser {
    return {
        fullName: user.name.toUpperCase(),
        emailDomain: user.email.split('@')[1]
    };
}

async function processUserData(user: User): Promise<void> {
    validateUser(user);
    const formattedUser = formatUser(user);
    await database.save(formattedUser);
    await emailService.sendWelcomeEmail(formattedUser);
}

Каждая функция теперь имеет одну чёткую цель, и их легко тестировать по отдельности.

Принцип 3: Используйте типы и интерфейсы для самодокументирования

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

Плохой пример:

function getDiscount(price: any, user: any) {
    if (user.isPremium) {
        return price * 0.8;
    }
    return price;
}

Хороший пример:

interface User {
    name: string;
    isPremium: boolean;
}

interface Product {
    price: number;
    title: string;
}

function getDiscountedPrice(product: Product, user: User): number {
    const discountRate = user.isPremium ? 0.8 : 1.0;
    return product.price * discountRate;
}

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

Принцип 4: Избегайте магических чисел и строк

«Магические» значения — это числа или строки, смысл которых неочевиден. Они делают код хрупким и сложным для изменений. Выносите их в константы с понятными именами.

Плохой пример:

if (user.role === 1) {
    // Что такое 1? Админ? Модератор?
    giveAccessToAdminPanel(user);
}

const timeout = 3000; // Почему 3000? Что это за таймаут?

Хороший пример:

enum UserRole {
    Admin = 1,
    Moderator = 2,
    User = 3
}

const ADMIN_PANEL_ACCESS_TIMEOUT_MS = 3000;

if (user.role === UserRole.Admin) {
    giveAccessToAdminPanel(user);
}

setTimeout(() => {
    revokeAccess(user);
}, ADMIN_PANEL_ACCESS_TIMEOUT_MS);

Теперь код стал самодокументируемым, а изменение значения константы происходит в одном месте.

Заключение

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

Помните: хороший код — это не тот, который работает, а тот, который легко поддерживать. TypeScript даёт для этого отличные инструменты, а Clean Code учит ими правильно пользоваться. Практикуйтесь, рефакторите старые проекты и пишите код, который будет понятен вам через год и вашим коллегам уже сегодня.

<<

Блоги

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