Files
2026-01-29 16:00:19 +03:00

8.0 KiB
Raw Permalink Blame History

title
title
Типизация

Типизация

Общие правила типизации

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

  • Использовать только строгую типизацию TypeScript для всех файлов логики, компонентов, хуков, API, сторов и утилит.
  • Всегда явно указывать типы для:
    • Пропсов компонентов
    • Параметров функций и методов
    • Возвращаемых значений функций и методов
    • Всех переменных состояния (в том числе в store)
    • Всех значимых переменных и констант, если их тип не очевиден из присваивания
  • Не использовать any и unknown без крайней необходимости. Если использование неизбежно — обязательно добавить комментарий с обоснованием.
  • Все интерфейсы, типы и enum всегда размещать в папке types/ на своём уровне абстракции (например, features/todo/types/).
  • Для DTO всегда использовать отдельную папку dto/ на уровне сущности или слоя.
  • Для сложных структур использовать отдельные интерфейсы или типы, размещая их в соответствующих файлах в папке types/.
  • Для DTO, enum, схем и других сущностей — всегда создавать отдельные типы/интерфейсы с осмысленными именами.
  • Ключи enum всегда писать ЗАГЛАВНЫМИ_БУКВАМИ (SCREAMING_SNAKE_CASE).
  • Не использовать неявное приведение типов и не полагаться на автоматический вывод, если это может снизить читаемость или безопасность.
  • Для массивов и объектов всегда указывать тип элементов/ключей.
  • Для возвращаемых значений асинхронных функций всегда указывать тип Promise.
  • Типизацию коллбеков и функций, передаваемых в пропсы, указывать инлайн, не выносить в отдельные типы.
  • Для типизации внешних библиотек использовать официальные типы или создавать собственные декларации при необходимости.
  • Не использовать устаревшие или не рекомендуемые паттерны типизации (например, Function, Object, {}).

Примеры

Интерфейс и типы для сущностей (всегда в папке types/)

// features/todo/types/todo-item.interface.ts

/**
 * Интерфейс задачи.
 */
export interface TodoItem {
  /** Уникальный идентификатор задачи. */
  id: string;
  /** Текст задачи. */
  text: string;
  /** Статус выполнения задачи. */
  completed: boolean;
}

Типизация enum (всегда в папке types/)

// features/todo/types/todo-status.enum.ts

/**
 * Перечисление статусов задачи.
 */
export enum TodoStatus {
  /** Активная задача. */
  ACTIVE = 'active',
  /** Выполненная задача. */
  COMPLETED = 'completed',
}

Типизация пропсов компонента

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>
));

Типизация функций и коллбеков (инлайн)

/**
 * Функция фильтрации задач.
 */
export const getCompletedTodos = (items: TodoItem[]): TodoItem[] => {
  return items.filter((t) => t.completed);
};

/**
 * Колбэк для обработки клика (инлайн).
 */
const handleClick = (id: string): void => {
  console.log('Clicked:', id);
};

Типизация асинхронных функций

/**
 * Получить задачи с сервера.
 */
export const fetchTodos = async (): Promise<TodoItem[]> => {
  const response = await fetch('/api/todos');
  return response.json();
};

Типизация состояния в store (интерфейс в types/)

// features/todo/types/todo-store.interface.ts

/**
 * Состояние хранилища задач.
 */
export interface TodoStoreState {
  /** Массив задач. */
  items: TodoItem[];
  /** Добавить задачу. */
  addTodo: (item: TodoItem) => void;
  /** Удалить задачу. */
  removeTodo: (id: string) => void;
}

Типизация DTO (всегда в папке dto/)

// 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;
}

Типизация внешних библиотек

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, {}).
  • Для внешних библиотек используются официальные типы или собственные декларации.
  • Нет неявного приведения типов, все типы читаемы и прозрачны.