Clean Code на TypeScript: принципы и примеры для начинающих
Чистый код (Clean Code) — это не просто модный термин, а философия разработки, которая помогает писать программы, понятные другим разработчикам (и вам самому через полгода). Для начинающих программистов на TypeScript освоение принципов чистого кода — это ключевой шаг к профессиональному росту. В этой статье мы разберем основные правила, приведем наглядные примеры и покажем, как сделать ваш код на TypeScript элегантным и поддерживаемым.
Почему важен чистый код?
Представьте, что вы читаете книгу, в которой нет абзацев, знаков препинания и все слова написаны слитно. Примерно так же выглядит грязный код для другого разработчика. Чистый код экономит время на отладке, упрощает добавление новых функций и снижает количество багов. TypeScript с его строгой типизацией уже помогает писать более надежный код, но без соблюдения принципов чистоты даже типизированный код может стать нечитаемым.
// Плохо: нечитаемо
function d(a:any,b:any){if(a>b){return a}else{return b}}
// Хорошо: чисто и понятно
function findMaxValue(firstNumber: number, secondNumber: number): number {
if (firstNumber > secondNumber) {
return firstNumber;
}
return secondNumber;
}
Основные принципы Clean Code на TypeScript
1. Осмысленные имена переменных и функций
Имя должно отвечать на вопросы "что?" и "зачем?". Избегайте однобуквенных сокращений (кроме индексов циклов) и абстрактных названий. Используйте camelCase для переменных и PascalCase для классов.
// Плохо
const d = new Date();
const arr = [1, 2, 3];
function p(x: number) { return x * 2; }
// Хорошо
const currentDate = new Date();
const numbersList: number[] = [1, 2, 3];
function doubleValue(value: number): number {
return value * 2;
}
2. Функции должны делать только одну вещь
Каждая функция должна решать одну задачу. Если функция делает больше одного действия — разбейте её на несколько маленьких. Это улучшает читаемость и тестируемость.
// Плохо: функция делает всё сразу
function processUserData(userData: string): void {
const parsed = JSON.parse(userData);
const isValid = parsed.name && parsed.email;
if (isValid) {
console.log(`User ${parsed.name} registered`);
saveToDatabase(parsed);
}
}
// Хорошо: каждая функция отвечает за своё
function parseUserData(rawData: string): User {
return JSON.parse(rawData);
}
function validateUserData(user: User): boolean {
return !!user.name && !!user.email;
}
function registerUser(userData: string): void {
const user = parseUserData(userData);
if (validateUserData(user)) {
console.log(`User ${user.name} registered`);
saveToDatabase(user);
}
}
3. Избегайте магических чисел и строк
Магические числа — это литералы, значение которых непонятно без контекста. Выносите их в константы с понятными именами.
// Плохо
if (user.age > 18) {
// ...
}
const discount = price * 0.1;
// Хорошо
const ADULT_AGE = 18;
const STANDARD_DISCOUNT_RATE = 0.1;
if (user.age > ADULT_AGE) {
// ...
}
const discount = price * STANDARD_DISCOUNT_RATE;
4. Используйте типы и интерфейсы правильно
TypeScript даёт мощные инструменты для описания данных. Не злоупотребляйте any, предпочитайте конкретные типы. Создавайте интерфейсы для сложных объектов.
// Плохо
function createUser(name: any, age: any) {
return { name, age, createdAt: new Date() };
}
// Хорошо
interface User {
name: string;
age: number;
createdAt: Date;
}
function createUser(name: string, age: number): User {
return {
name,
age,
createdAt: new Date()
};
}
Практические примеры для начинающих
Пример 1: Работа с API
Рассмотрим типичную задачу — получение данных с сервера. Грязный код часто смешивает логику запроса, обработки ошибок и форматирования данных.
// Грязный код
async function getData() {
const res = await fetch('https://api.example.com/users');
const data = await res.json();
let result = [];
for (let i = 0; i < data.length; i++) {
if (data[i].active) {
result.push({ name: data[i].name, email: data[i].email });
}
}
return result;
}
// Чистый код
interface User {
id: number;
name: string;
email: string;
active: boolean;
}
interface FormattedUser {
name: string;
email: string;
}
async function fetchUsers(): Promise<User[]> {
const response = await fetch('https://api.example.com/users');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
}
function filterActiveUsers(users: User[]): FormattedUser[] {
return users
.filter(user => user.active)
.map(user => ({
name: user.name,
email: user.email
}));
}
async function getActiveUsers(): Promise<FormattedUser[]> {
const users = await fetchUsers();
return filterActiveUsers(users);
}
Пример 2: Обработка ошибок
Не игнорируйте ошибки. Используйте типизированные исключения и обрабатывайте их на соответствующем уровне.
// Плохо
try {
const data = riskyOperation();
} catch (error) {
console.log('Error occurred');
}
// Хорошо
class NetworkError extends Error {
constructor(message: string) {
super(message);
this.name = 'NetworkError';
}
}
try {
const data = riskyOperation();
} catch (error) {
if (error instanceof NetworkError) {
console.error('Network problem:', error.message);
// Повторная попытка или уведомление пользователя
} else {
console.error('Unexpected error:', error);
// Логирование в систему мониторинга
}
}
Заключение
Clean Code на TypeScript — это набор практик, которые превращают ваш код из "работающего" в "профессиональный". Начните с малого: давайте осмысленные имена, разбивайте большие функции на маленькие, используйте типы и избегайте магических значений. Со временем эти принципы войдут в привычку, и вы заметите, как повысится качество вашего кода и скорость разработки.
Помните: чистый код — это не перфекционизм, а уважение к себе и