Введение: почему документация — это инвестиция, а не трата времени
Каждый разработчик сталкивался с ситуацией: возвращаясь к собственному коду через месяц, вы с трудом вспоминаете, зачем нужен тот или иной параметр. Что уж говорить о новых членах команды, которые пытаются разобраться в вашем проекте. Качественная документация для TypeScript проекта — это не просто приятное дополнение, а критически важный элемент, который ускоряет онбординг, снижает количество багов и делает код поддерживаемым.
TypeScript, будучи надстройкой над JavaScript, предоставляет мощную систему типов. Однако типы сами по себе не всегда отвечают на вопрос «почему». Документация восполняет этот пробел. В этой статье мы разберем полный цикл: от выбора стиля комментариев до генерации статического сайта с документацией.
1. Основы: JSDoc, TSDoc и TypeScript
Для документирования TypeScript кода исторически сложились два основных стандарта: JSDoc и TSDoc. JSDoc — это старый добрый формат, который пришёл из мира JavaScript. TSDoc — более современный стандарт, оптимизированный специально для TypeScript. Оба подхода используют комментарии в формате /** ... */.
Рассмотрим базовый пример с использованием JSDoc:
/**
* Вычисляет сумму двух чисел.
* @param a - Первое слагаемое
* @param b - Второе слагаемое
* @returns Сумма a и b
*/
function add(a: number, b: number): number {
return a + b;
}
А вот как это выглядит в стиле TSDoc с использованием тегов @param и @returns:
/**
* Вычисляет сумму двух чисел.
* @param a - Первое слагаемое
* @param b - Второе слагаемое
* @returns Сумма a и b
*/
function add(a: number, b: number): number {
return a + b;
}
Разница минимальна, но TSDoc добавляет поддержку специфических для TypeScript конструкций, таких как дженерики и условные типы.
1.1 Документирование интерфейсов и типов
Особое внимание стоит уделить интерфейсам и типам. Они являются «скелетом» TypeScript проекта. Вот пример хорошо документированного интерфейса:
/**
* Представляет пользователя системы.
*/
interface User {
/** Уникальный идентификатор пользователя */
id: string;
/** Полное имя пользователя */
name: string;
/** Email адрес (должен быть уникальным) */
email: string;
/** Дата последнего входа в систему (опционально) */
lastLogin?: Date;
/** Роль пользователя в системе */
role: 'admin' | 'user' | 'moderator';
}
Обратите внимание: каждый параметр интерфейса имеет свой /** ... */ комментарий. Это позволяет IDE (например, VS Code) показывать подсказки при использовании этого интерфейса.
2. Продвинутые техники: дженерики и условные типы
TypeScript славится своей системой типов, и документация должна отражать её сложность. Особенно это касается дженериков (generic types) и условных типов (conditional types).
Рассмотрим пример дженерика с документацией:
/**
* Создаёт массив из одного элемента с типом T.
* @template T - Тип элемента, который будет помещён в массив
* @param item - Элемент для обёртывания
* @returns Массив, содержащий переданный элемент
*/
function wrapInArray<T>(item: T): T[] {
return [item];
}
Тег @template явно указывает, что такое T. Это особенно полезно, когда дженериков несколько или они имеют сложную взаимосвязь.
Для условных типов документация становится ещё важнее. Пример:
/**
* Извлекает тип значения из Promise, если передан Promise.
* Иначе возвращает исходный тип.
* @template T - Тип, который может быть Promise или нет
* @example
* // Для Promise<number> вернёт number
* type Result = UnwrapPromise<Promise<number>>; // number
* // Для string вернёт string
* type Result2 = UnwrapPromise<string>; // string
*/
type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;
Блок @example здесь — лучший друг разработчика. Он показывает, как тип работает на практике, что гораздо понятнее сухого описания.
3. Инструменты генерации документации
Писать комментарии — это полдела. Чтобы команда могла ими пользоваться, нужно сгенерировать удобочитаемую документацию. Для TypeScript лучшим инструментом является TypeDoc. Он преобразует ваши JSDoc/TSDoc комментарии в статический HTML-сайт.
3.1 Установка и настройка TypeDoc
Установка проста:
npm install --save-dev typedoc
Добавьте скрипт в package.json:
{
"scripts": {
"docs": "typedoc --out docs src"
}
}
Команда npm run docs просканирует все файлы в папке src и сгенерирует документацию в папку docs.
3.2 Конфигурация TypeDoc
Для более тонкой настройки создайте файл typedoc.json в корне проекта:
{
"entryPoints": ["src/index.ts"],
"out": "docs",
"exclude": ["**/node_modules/**", "**/*.test.ts"],
"name": "My TypeScript Library",
"includeVersion": true,
"excludePrivate": true,
"excludeProtected": true
}
Параметр excludePrivate убирает из документации приватные методы и свойства, что делает итоговый сайт чище и понятнее для пользователей вашей библиотеки.
4. Лучшие практики и частые ошибки
На основе многолетнего опыта работы с TypeScript проектами, можно выделить несколько золотых правил:
- Документируйте «почему», а не «что». Код и так показывает, что он делает. Комментарии должны объяснять причину выбора именно такого решения.
- Не дублируйте типы. Если тип переменной указан в коде (
name: string), не пишите в комментарии «имя — строка». Лучше напишите «полное имя пользователя в формате "Имя Фамилия