Menu

Комментарии в TypeScript: JSDoc, @ts-ignore, @ts-expect-error

TypeScript использует комментарии JavaScript // и /* */, а также комментарии JSDoc /** */, которые редакторы показывают при наведении. Кроме того, он читает несколько особых комментариев: @ts-expect-error, @ts-ignore, @ts-nocheck, @ts-check и директивы /// <reference>.

На этой странице есть исполняемые редакторы: меняйте, запускайте и сразу видите результат.

Комментарии в TypeScript это комментарии JavaScript: // до конца строки и /* */ для блока. Блочный комментарий, начинающийся с /**, это документирующий комментарий (JSDoc), который редакторы показывают при наведении на то, что он описывает. Кроме того, TypeScript читает несколько особых комментариев, которые меняют то, как компилятор проверяет код.

Вывод:

212

Комментарии не влияют на программу. Не влияют они и на проверку типов, за исключением комментариев-директив, о которых ниже.

Однострочные и блочные комментарии

// превращает в комментарий всё, что идёт после него в строке; это ещё и быстрый способ отключить строку кода. /* */ может стоять в середине строки или занимать много строк.

Блочные комментарии не вкладываются. Первый */ завершает комментарий, поэтому обёртка кода, в котором уже есть блочный комментарий, ломается:

/* outer comment /* inner comment */ this text is now code */

Компилятор пытается прочитать this text is now code */ как код и сообщает о синтаксической ошибке. Чтобы закомментировать участок с блочными комментариями, ставьте // в каждой строке; большинство редакторов делают это по Ctrl+/ (Cmd+/ в macOS).

Документирующие комментарии JSDoc

Комментарий /** ... */ непосредственно перед функцией, классом, методом, свойством, интерфейсом или переменной документирует их. Редакторы показывают его текст во всплывающей подсказке и в автодополнении, а генераторы документации вроде TypeDoc превращают его в справочные страницы. TSDoc, стандарт для таких комментариев в коде на TypeScript, начатый Microsoft, использует тот же синтаксис для распространённых тегов:

ТегЗначение
@param name descriptionОписывает параметр
@returns descriptionОписывает возвращаемое значение
@throws descriptionОписывает ошибку, которую может выбросить функция
@exampleНачинает блок примера, обычно за ним идёт блок кода
@deprecated reasonПомечает API как устаревший; редакторы показывают его зачёркнутым
@see или {@link Name}Указывает на связанный код
@remarksБолее длинное пояснение после строки с кратким описанием

В файле .ts не повторяйте типы в JSDoc. Типами являются аннотации в коде, а теги типов JSDoc там игнорируются: /** @type {string} */ const v: number = 5; компилируется без замечаний, потому что учитывается только : number.

В редакторе при наведении на transfer или balance в любом месте проекта видны эти описания.

Пометка кода как устаревшего

@deprecated не вызывает ошибку компиляции. Он сообщает редакторам, что каждое использование устаревшей функции нужно показывать зачёркнутым, а причину выводить при наведении; это мягкий способ направить вызывающий код к замене:

Вывод:

$19.99
19.99 EUR

@ts-expect-error и @ts-ignore

Эти два комментария заглушают ошибки типов на следующей строке. Иногда это правильное решение: тест, который проверяет, как функция обрабатывает неверный ввод во время выполнения, или известный пробел в типах библиотеки.

Вывод:

runtime error: text.toUpperCase is not a function

Без комментария shout(42) это ошибка компиляции (TS2345). С ним файл компилируется, и вызов доходит до времени выполнения, в чём и состоит смысл этого теста.

Разница между двумя директивами проявляется, когда ошибка исчезает. @ts-expect-error требует, чтобы ошибка для подавления была, поэтому устаревший комментарий сам становится ошибкой:

index.ts(6,1): error TS2578: Unused '@ts-expect-error' directive.

// @ts-ignore на том же месте молчит и пока ошибка есть, и после того, как она исчезла. Поэтому @ts-expect-error лучше как вариант по умолчанию: когда кто-то исправит типы, компилятор скажет, что подавление можно убрать. Всегда пишите причину после директивы, как в примере выше, чтобы следующий читатель понимал, зачем она там.

Обе директивы действуют только на следующую строку и на все ошибки в ней. Для обхода проверки у целого значения явное as unknown as T или проверка во время выполнения обычно понятнее, чем комментарий-подавление.

@ts-nocheck и @ts-check

// @ts-nocheck в начале файла отключает проверку типов для всего файла. Он должен идти первым, до любого кода: если поставить его ниже, он игнорируется и ошибки по-прежнему видны.

// @ts-nocheck
const n: number = "not a number"; // no error reported

Это полезно при миграции большой кодовой базы на JavaScript и подозрительно в любом другом месте.

// @ts-check делает обратное в файле JavaScript: включает проверку типов для этого файла .js с выводом типов и типами из JSDoc, даже если checkJs в tsconfig.json выключен (файл всё равно должен входить в проект через allowJs):

// @ts-check

/**
 * @param {number} cents
 * @returns {string}
 */
function formatCents(cents) {
    return (cents / 100).toFixed(2);
}

formatCents("12"); // error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.

В файлах JavaScript теги JSDoc являются типами; так многие проекты получают проверку типов, не переводя файлы в .ts.

Директивы с тройным слешем

Комментарий вида /// <reference ... /> в самом начале файла это директива компилятора:

/// <reference types="node" />
/// <reference lib="es2023.array" />
/// <reference path="./globals.d.ts" />
  • types="node" добавляет в программу пакет @types, как если бы он был указан в "types" в tsconfig.json.
  • lib="..." добавляет в программу встроенную библиотеку, как параметр lib.
  • path="..." подключает другой файл; используется в основном внутри файлов .d.ts.

В прикладном коде инструкции import и настройки tsconfig.json заменяют почти все такие случаи; эти директивы встречаются в основном в файлах объявлений и сгенерированном коде вроде vite-env.d.ts в Vite. Для быстрой демонстрации: lib делает доступным в этом файле более новый метод массива:

Комментарии в скомпилированном выводе

tsc сохраняет комментарии в записываемом JavaScript. Задайте "removeComments": true, чтобы удалить их; комментарии, начинающиеся с /*!, сохраняются и в этом случае, так принято оформлять заголовки с лицензией:

/*! MyLib v1.2.0 | MIT License */

Комментарии JSDoc также копируются в файлы .d.ts, когда включён declaration, поэтому пользователи библиотеки видят описания в своём редакторе.

Часто задаваемые вопросы

Как написать комментарий в TypeScript?

Так же, как в JavaScript: // начинает комментарий до конца строки, а /* ... */ оборачивает комментарий, который может занимать несколько строк. Блочный комментарий, начинающийся с /**, это документирующий комментарий (JSDoc), который редакторы показывают при наведении на документируемую функцию, класс или свойство.

Чем @ts-ignore отличается от @ts-expect-error?

Оба заглушают ошибки типов на следующей строке. // @ts-expect-error дополнительно проверяет, что ошибка там есть: если строка перестаёт её содержать, компилятор сообщает error TS2578: Unused '@ts-expect-error' directive., и устаревшее подавление становится заметным. // @ts-ignore молчит всегда. Предпочитайте @ts-expect-error.

Как игнорировать ошибки TypeScript во всём файле?

Поставьте // @ts-nocheck в начало файла, до любого кода. Тогда компилятор не сообщает об ошибках типов в этом файле (синтаксические ошибки всё равно видны). Это инструмент для миграции; для одной строки используйте // @ts-expect-error.

Попадают ли комментарии в скомпилированный JavaScript?

Да, по умолчанию tsc сохраняет комментарии в выводе. С "removeComments": true он их удаляет, кроме комментариев, начинающихся с /*!, которые сохраняются для заголовков с лицензией. Бандлеры и минификаторы обычно удаляют их в продакшен-сборках.

Нужно ли писать типы в комментариях JSDoc в файле .ts?

Нет. В файлах .ts теги типов JSDoc вроде @type {string} или @param {number} x при проверке типов игнорируются; типами являются аннотации в коде. Используйте JSDoc в файлах .ts для описаний, а типы в JSDoc только в файлах .js, проверяемых через // @ts-check или checkJs.

Coddy programming languages illustration

Учитесь программировать с Coddy

НАЧАТЬ