2026-01-29 16:00:19 +03:00
|
|
|
|
---
|
|
|
|
|
|
title: Стиль кода
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
# Стиль кода
|
|
|
|
|
|
|
|
|
|
|
|
Раздел описывает единые правила оформления кода: отступы, переносы, кавычки, порядок импортов и базовую читаемость.
|
|
|
|
|
|
|
2026-01-30 02:02:32 +03:00
|
|
|
|
## Отступы
|
2026-01-29 16:00:19 +03:00
|
|
|
|
|
2026-01-30 02:02:32 +03:00
|
|
|
|
- 2 пробела (не табы).
|
2026-01-29 16:00:19 +03:00
|
|
|
|
|
|
|
|
|
|
## Длина строк
|
|
|
|
|
|
|
|
|
|
|
|
- Ориентироваться на 100 символов, но превышение допустимо, если строка читается легко.
|
|
|
|
|
|
- Переносить выражение на новые строки, когда строка становится плохо читаемой.
|
|
|
|
|
|
- Не переносить строку внутри строковых литералов без необходимости.
|
|
|
|
|
|
|
|
|
|
|
|
**Хорошо**
|
|
|
|
|
|
```ts
|
|
|
|
|
|
const config = createRequestConfig(
|
|
|
|
|
|
endpoint,
|
|
|
|
|
|
{
|
|
|
|
|
|
headers: {
|
|
|
|
|
|
'X-Request-Id': requestId,
|
|
|
|
|
|
'X-User-Id': userId,
|
|
|
|
|
|
},
|
|
|
|
|
|
params: {
|
|
|
|
|
|
page,
|
|
|
|
|
|
pageSize,
|
|
|
|
|
|
sort: 'createdAt',
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
timeoutMs,
|
|
|
|
|
|
);
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**Плохо**
|
|
|
|
|
|
```ts
|
2026-01-30 02:02:32 +03:00
|
|
|
|
// Плохо: длинная строка с вложенными структурами плохо читается.
|
2026-01-29 16:00:19 +03:00
|
|
|
|
const config = createRequestConfig(endpoint, { headers: { 'X-Request-Id': requestId, 'X-User-Id': userId }, params: { page, pageSize, sort: 'createdAt' } }, timeoutMs);
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## Кавычки
|
|
|
|
|
|
|
|
|
|
|
|
- В JavaScript/TypeScript использовать одинарные кавычки.
|
|
|
|
|
|
- В JSX/TSX для атрибутов использовать двойные кавычки.
|
|
|
|
|
|
- Шаблонные строки использовать только при интерполяции или многострочном тексте.
|
|
|
|
|
|
|
|
|
|
|
|
**Хорошо**
|
|
|
|
|
|
```ts
|
|
|
|
|
|
const label = 'Сохранить';
|
|
|
|
|
|
const title = `Привет, ${name}`;
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
```tsx
|
|
|
|
|
|
<input type="text" placeholder="Введите имя" />
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**Плохо**
|
|
|
|
|
|
```ts
|
2026-01-30 02:02:32 +03:00
|
|
|
|
// Плохо: двойные кавычки в TS и конкатенация вместо шаблонной строки.
|
2026-01-29 16:00:19 +03:00
|
|
|
|
const label = "Сохранить";
|
|
|
|
|
|
const title = 'Привет, ' + name;
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
```tsx
|
2026-01-30 02:02:32 +03:00
|
|
|
|
// Плохо: одинарные кавычки в JSX-атрибутах.
|
2026-01-29 16:00:19 +03:00
|
|
|
|
<input type='text' placeholder='Введите имя' />
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## Точки с запятой и запятые
|
|
|
|
|
|
|
|
|
|
|
|
- Допускаются упущения точки с запятой, если код остаётся читаемым и однозначным.
|
|
|
|
|
|
- В многострочных массивах, объектах и параметрах функции запятая в конце допускается, но не обязательна.
|
|
|
|
|
|
|
|
|
|
|
|
## Импорты
|
|
|
|
|
|
|
|
|
|
|
|
- В именованных импортах использовать пробелы внутри фигурных скобок.
|
|
|
|
|
|
- Типы импортировать через `import type`.
|
|
|
|
|
|
- `default` импорт и экспорт избегать, использовать именованные.
|
|
|
|
|
|
- Избегать импорта всего модуля через `*`.
|
|
|
|
|
|
|
|
|
|
|
|
**Хорошо**
|
|
|
|
|
|
```ts
|
|
|
|
|
|
import { MyComponent } from 'MyComponent';
|
|
|
|
|
|
import type { User } from '../model/types';
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**Плохо**
|
|
|
|
|
|
```ts
|
2026-01-30 02:02:32 +03:00
|
|
|
|
// Плохо: default импорт и отсутствие пробелов в именованном импорте.
|
2026-01-29 16:00:19 +03:00
|
|
|
|
import MyComponent from 'MyComponent';
|
|
|
|
|
|
import type {User} from '../model/types';
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## Ранние возвраты (early return)
|
|
|
|
|
|
|
|
|
|
|
|
- Использовать ранние возвраты для упрощения чтения.
|
|
|
|
|
|
- Избегать `else` после `return`.
|
|
|
|
|
|
|
|
|
|
|
|
**Хорошо**
|
|
|
|
|
|
```ts
|
|
|
|
|
|
const getName = (user?: { name: string }) => {
|
|
|
|
|
|
if (!user) {
|
|
|
|
|
|
return 'Гость';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return user.name;
|
|
|
|
|
|
};
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**Плохо**
|
|
|
|
|
|
```ts
|
2026-01-30 02:02:32 +03:00
|
|
|
|
// Плохо: лишний else после return усложняет чтение.
|
2026-01-29 16:00:19 +03:00
|
|
|
|
const getName = (user?: { name: string }) => {
|
|
|
|
|
|
if (user) {
|
|
|
|
|
|
return user.name;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return 'Гость';
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## Форматирование объектов и массивов
|
|
|
|
|
|
|
|
|
|
|
|
- В многострочных объектах каждое свойство на новой строке.
|
|
|
|
|
|
- В многострочных массивах каждый элемент на новой строке.
|
|
|
|
|
|
- Объекты и массивы можно писать в одну строку, если длина строки не превышает 100 символов.
|
|
|
|
|
|
- В однострочных объектах и массивах использовать пробелы после запятых.
|
|
|
|
|
|
|
|
|
|
|
|
**Хорошо**
|
|
|
|
|
|
```ts
|
2026-01-30 02:02:32 +03:00
|
|
|
|
const roles = ['admin', 'editor', 'viewer'];
|
2026-01-29 16:00:19 +03:00
|
|
|
|
const options = { id: 1, name: 'User' };
|
|
|
|
|
|
|
|
|
|
|
|
const config = {
|
|
|
|
|
|
url: '/api/users',
|
|
|
|
|
|
method: 'GET',
|
|
|
|
|
|
params: { page: 1, pageSize: 20 },
|
|
|
|
|
|
};
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**Плохо**
|
|
|
|
|
|
```ts
|
2026-01-30 02:02:32 +03:00
|
|
|
|
// Плохо: нет пробелов после запятых и объект слишком длинный для одной строки.
|
|
|
|
|
|
const roles = ['admin','editor','viewer'];
|
2026-01-29 16:00:19 +03:00
|
|
|
|
const options = { id: 1,name: 'User' };
|
|
|
|
|
|
const config = { url: '/api/users', method: 'GET', params: { page: 1, pageSize: 20 } };
|
|
|
|
|
|
```
|