Устаревшие @ts-ignore
Находит // @ts-ignore, который больше ничего не подавляет — код под ним в какой-то момент починили, а комментарий забыли убрать, и теперь он молча прячет уже ДРУГУЮ ошибку, если она там появится.
devtoolz stale-ts-ignore [dir] [options]Реальный вывод — функция, чьё тело типчекается чисто само по себе, с забытым @ts-ignore над строкой:
Checked 1 @ts-ignore directive.
1 stale @ts-ignore found:
src/example.ts:2 @ts-ignore doesn't suppress anything — the line below it typechecks cleanly without itРеально нужная директива — с настоящей ошибкой типов прямо под ней — не репортится:
Checked 1 @ts-ignore directive.
All clear — didn't even break a sweat.Почему это не дублирует @ts-expect-error
TypeScript сам, начиная с 3.9, репортит неиспользуемую директиву @ts-expect-error как настоящую диагностику (Unused '@ts-expect-error' directive) — это ровно та причина, по которой @ts-expect-error вообще появился как «более безопасная» альтернатива. Для @ts-ignore эквивалентной встроенной проверки нет и никогда не будет — этот пробел и есть весь смысл существования команды.
Как определяется «устарела»
У TypeScript нет публичного API «была ли эта конкретная @ts-ignore реально нужна» — спросить компилятора напрямую нельзя. Практический путь: прогнать реальный тайпчек всего проекта дважды. Один раз как есть. Второй раз — на виртуальной копии исходников, где каждый комментарий @ts-ignore замаскирован пробелами той же длины (номера строк не съезжают) — а затем сравнить, появилась ли на месте каждой директивы НАСТОЯЩАЯ новая диагностика, которой не было в первом прогоне. Не появилась ничего нового — директива ничего не подавляла.
Это полноценный ts.Program по всему проекту (tsconfig.json автоопределяется так же, как у case-check/readme-check), а не изолированная проверка отдельного файла — так что команда корректно понимает и директивы, которые оказываются ненужными только с учётом остального проекта.
Самая дорогая команда здесь
Построение реального проекта дважды по вычислениям ближе к tsc --noEmit всего проекта, чем к любой другой команде в этом наборе. Две вещи не дают этому стать неприятным сюрпризом:
- Если в проекте нет вообще ни одной
@ts-ignore, дорогая часть вообще не запускается — мгновенный чистый отчёт. - Иначе перед началом реальной работы выводится статусная строка, так что медленный прогон на большом проекте никогда не выглядит как тихое зависание:
Running a project-wide typecheck, twice — this can take a while on a large project…Эта строка идёт в stderr, не в stdout — она никогда не примешивается к --json-выводу.
Директива, отделённая от цели пустой строкой
Настоящее правило самого TypeScript: @ts-ignore подавляет только строку НЕПОСРЕДСТВЕННО под собой — пустая строка между ними делает директиву не действующей. Команда не реализует эту проверку отдельно — ей это и не нужно. Если пустая строка ломает директиву, настоящий компилятор уже ничего не подавляет там в первом (as-is) прогоне, так что сравнение со вторым прогоном само по себе не покажет никакой новой диагностики в любом случае — репортится как устаревшая, по точной и честной причине: она сейчас ничего не подавляет.
.vue-файлы
Обычный ts.Program вообще не может включить .vue-файлы в прогон по всему проекту — нет поддержки SFC без подключения собственной машинерии vue-tsc, что вне контракта этой команды. Вместо этого блок <script> каждого .vue-файла получает изолированную проверку одного файла — тот же приём с виртуальным файлом, что readme-check использует для своих код-блоков: реальные импорты всё так же резолвятся против реального пакета на диске, но диагностика, которая могла бы всплыть только через использование этого файла где-то ещё, не видна. То же самое, уже принятое и задокументированное ограничение, что и у изолированной проверки readme-check.
Checked 1 @ts-ignore directive.
1 stale @ts-ignore found:
src/Widget.vue:7 @ts-ignore doesn't suppress anything — the line below it typechecks cleanly without itОпции
[dir]
Директория пакета для проверки (по умолчанию: .).
--tsconfig <path>
tsconfig.json, откуда читать опции компилятора — по умолчанию автоопределяется.
--ignore <glob>
Дополнительный паттерн игнорирования (повторяемый) поверх встроенных по умолчанию — применяется только к поиску .vue-файлов (реальные файлы TS/JS-проекта берутся из самого tsconfig.json).
--no-respect-gitignore
Не учитывать также .gitignore проекта при поиске .vue-файлов.
Пример:
devtoolz stale-ts-ignore # tsconfig.json в текущей директории
devtoolz stale-ts-ignore path/to/package # конкретная директория
devtoolz stale-ts-ignore --tsconfig tsconfig.build.json