188 lines
8.0 KiB
Markdown
188 lines
8.0 KiB
Markdown
|
|
---
|
|||
|
|
title: Типизация
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# Типизация
|
|||
|
|
|
|||
|
|
## Общие правила типизации
|
|||
|
|
|
|||
|
|
> Данный раздел определяет единые требования к типизации для всего проекта. Соблюдение этих правил обеспечивает читаемость, предсказуемость и безопасность кода.
|
|||
|
|
|
|||
|
|
- Использовать только строгую типизацию TypeScript для всех файлов логики, компонентов, хуков, API, сторов и утилит.
|
|||
|
|
- Всегда явно указывать типы для:
|
|||
|
|
- Пропсов компонентов
|
|||
|
|
- Параметров функций и методов
|
|||
|
|
- Возвращаемых значений функций и методов
|
|||
|
|
- Всех переменных состояния (в том числе в store)
|
|||
|
|
- Всех значимых переменных и констант, если их тип не очевиден из присваивания
|
|||
|
|
- Не использовать `any` и `unknown` без крайней необходимости. Если использование неизбежно — обязательно добавить комментарий с обоснованием.
|
|||
|
|
- Все интерфейсы, типы и enum всегда размещать в папке `types/` на своём уровне абстракции (например, `features/todo/types/`).
|
|||
|
|
- Для DTO всегда использовать отдельную папку `dto/` на уровне сущности или слоя.
|
|||
|
|
- Для сложных структур использовать отдельные интерфейсы или типы, размещая их в соответствующих файлах в папке `types/`.
|
|||
|
|
- Для DTO, enum, схем и других сущностей — всегда создавать отдельные типы/интерфейсы с осмысленными именами.
|
|||
|
|
- Ключи enum всегда писать ЗАГЛАВНЫМИ_БУКВАМИ (SCREAMING_SNAKE_CASE).
|
|||
|
|
- Не использовать неявное приведение типов и не полагаться на автоматический вывод, если это может снизить читаемость или безопасность.
|
|||
|
|
- Для массивов и объектов всегда указывать тип элементов/ключей.
|
|||
|
|
- Для возвращаемых значений асинхронных функций всегда указывать тип Promise.
|
|||
|
|
- Типизацию коллбеков и функций, передаваемых в пропсы, указывать инлайн, не выносить в отдельные типы.
|
|||
|
|
- Для типизации внешних библиотек использовать официальные типы или создавать собственные декларации при необходимости.
|
|||
|
|
- Не использовать устаревшие или не рекомендуемые паттерны типизации (например, `Function`, `Object`, `{}`).
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### Примеры
|
|||
|
|
|
|||
|
|
#### Интерфейс и типы для сущностей (всегда в папке types/)
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
// features/todo/types/todo-item.interface.ts
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Интерфейс задачи.
|
|||
|
|
*/
|
|||
|
|
export interface TodoItem {
|
|||
|
|
/** Уникальный идентификатор задачи. */
|
|||
|
|
id: string;
|
|||
|
|
/** Текст задачи. */
|
|||
|
|
text: string;
|
|||
|
|
/** Статус выполнения задачи. */
|
|||
|
|
completed: boolean;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### Типизация enum (всегда в папке types/)
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
// features/todo/types/todo-status.enum.ts
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Перечисление статусов задачи.
|
|||
|
|
*/
|
|||
|
|
export enum TodoStatus {
|
|||
|
|
/** Активная задача. */
|
|||
|
|
ACTIVE = 'active',
|
|||
|
|
/** Выполненная задача. */
|
|||
|
|
COMPLETED = 'completed',
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### Типизация пропсов компонента
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
import { FC, memo } from 'react';
|
|||
|
|
import { TodoItem } from './types/todo-item.interface';
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Список задач.
|
|||
|
|
*/
|
|||
|
|
export interface TodoListProps {
|
|||
|
|
/** Массив задач. */
|
|||
|
|
items: TodoItem[];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export const TodoList: FC<TodoListProps> = memo(({ items }) => (
|
|||
|
|
<ul>
|
|||
|
|
{items.map((item) => (
|
|||
|
|
<li key={item.id}>{item.text}</li>
|
|||
|
|
))}
|
|||
|
|
</ul>
|
|||
|
|
));
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### Типизация функций и коллбеков (инлайн)
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
/**
|
|||
|
|
* Функция фильтрации задач.
|
|||
|
|
*/
|
|||
|
|
export const getCompletedTodos = (items: TodoItem[]): TodoItem[] => {
|
|||
|
|
return items.filter((t) => t.completed);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Колбэк для обработки клика (инлайн).
|
|||
|
|
*/
|
|||
|
|
const handleClick = (id: string): void => {
|
|||
|
|
console.log('Clicked:', id);
|
|||
|
|
};
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### Типизация асинхронных функций
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
/**
|
|||
|
|
* Получить задачи с сервера.
|
|||
|
|
*/
|
|||
|
|
export const fetchTodos = async (): Promise<TodoItem[]> => {
|
|||
|
|
const response = await fetch('/api/todos');
|
|||
|
|
return response.json();
|
|||
|
|
};
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### Типизация состояния в store (интерфейс в types/)
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
// features/todo/types/todo-store.interface.ts
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Состояние хранилища задач.
|
|||
|
|
*/
|
|||
|
|
export interface TodoStoreState {
|
|||
|
|
/** Массив задач. */
|
|||
|
|
items: TodoItem[];
|
|||
|
|
/** Добавить задачу. */
|
|||
|
|
addTodo: (item: TodoItem) => void;
|
|||
|
|
/** Удалить задачу. */
|
|||
|
|
removeTodo: (id: string) => void;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### Типизация DTO (всегда в папке dto/)
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
// features/todo/dto/create-todo.dto.ts
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* DTO для создания задачи.
|
|||
|
|
*/
|
|||
|
|
export interface CreateTodoDto {
|
|||
|
|
/** Текст задачи. */
|
|||
|
|
text: string;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// features/todo/dto/todo-response.dto.ts
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* DTO ответа сервера.
|
|||
|
|
*/
|
|||
|
|
export interface TodoResponseDto {
|
|||
|
|
/** Созданная задача. */
|
|||
|
|
todo: TodoItem;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### Типизация внешних библиотек
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
import type { AxiosResponse } from 'axios';
|
|||
|
|
|
|||
|
|
export const getData = async (): Promise<AxiosResponse<TodoItem[]>> => {
|
|||
|
|
// ...
|
|||
|
|
};
|
|||
|
|
```
|
|||
|
|
### Чек-лист проверки типизации
|
|||
|
|
|
|||
|
|
- [ ] Все пропсы компонентов явно типизированы через интерфейс или тип в папке `types/`.
|
|||
|
|
- [ ] Все параметры и возвращаемые значения функций и методов явно типизированы.
|
|||
|
|
- [ ] Все переменные состояния (в том числе в store) имеют явные типы.
|
|||
|
|
- [ ] Все интерфейсы, типы и enum размещены в папке `types/` на своём уровне абстракции.
|
|||
|
|
- [ ] Ключи всех enum написаны ЗАГЛАВНЫМИ_БУКВАМИ (SCREAMING_SNAKE_CASE).
|
|||
|
|
- [ ] Все DTO размещены в папке `dto/` на своём уровне абстракции.
|
|||
|
|
- [ ] Не используется `any` и `unknown` без крайней необходимости и поясняющего комментария.
|
|||
|
|
- [ ] Для сложных структур используются отдельные интерфейсы или типы.
|
|||
|
|
- [ ] Для массивов и объектов указан тип элементов/ключей.
|
|||
|
|
- [ ] Для асинхронных функций указан тип Promise с конкретным типом результата.
|
|||
|
|
- [ ] Типы коллбеков и функций, передаваемых в пропсы, указаны инлайн.
|
|||
|
|
- [ ] Не используются устаревшие типы (`Function`, `Object`, `{}`).
|
|||
|
|
- [ ] Для внешних библиотек используются официальные типы или собственные декларации.
|
|||
|
|
- [ ] Нет неявного приведения типов, все типы читаемы и прозрачны.
|