TypeScript 7.0 RC: новый компилятор на Go уже можно проверить в своих проектах

от автора

Команда TypeScript выпустила релиз-кандидат TypeScript 7.0. Это важный релиз не из-за пары новых флагов, а из-за смены основы компилятора: кодовую базу перенесли с TypeScript/JavaScript на Go.

Заявка серьёзная: в ряде сценариев TypeScript 7.0 должен работать примерно в 10 раз быстрее TypeScript 6.0. Ускорение появилось не из-за изменения языка, а за счёт скомпилированного кода и более активного использования параллельной обработки.

Что поменялось

Главное изменение — новая реализация компилятора. Команда не стала заново придумывать TypeScript, а перенесла существующую логику на Go. Проверка типов должна вести себя так же, как в TypeScript 6.0: идея в том, чтобы сохранить совместимость, но заметно ускорить работу.

На практике это значит, что проекты, которые собираются на TypeScript 6.0, в большинстве случаев должны собираться и на TypeScript 7.0. Только быстрее. Самый заметный эффект ожидается в больших кодовых базах, где проверка типов давно стала ощутимой частью локальной разработки и CI.

Релиз-кандидат уже можно поставить из npm:

npm install -D typescript@rc

Проверить версию:

npx tsc --version

Для текущего RC команда указывает версию 7.0.1-rc.

Откуда взялось ускорение

В TypeScript 7.0 часть работы компилятора выполняется параллельно: разбор файлов, проверка типов и генерация результата.

С разбором и генерацией всё относительно понятно: многие операции можно делать независимо по файлам. С проверкой типов сложнее. Там есть зависимости между файлами, общие типы, глобальная область видимости и порядок анализа, который нельзя просто игнорировать.

Поэтому TypeScript 7.0 использует фиксированное количество проверяющих процессов. По умолчанию — четыре. Управлять этим можно через флаг:

--checkers

На крупном проекте увеличение значения может ускорить сборку, но за это придётся заплатить памятью. В CI или на слабой машине иногда разумнее, наоборот, уменьшить число процессов.

Для проектов с project references появился отдельный флаг:

--builders

Он задаёт количество параллельных сборщиков. Здесь важно помнить про перемножение: например, --checkers 4 --builders 4 может дать до 16 одновременно работающих проверяющих процессов. Для локальной машины или небольшого CI-раннера это легко окажется перебором.

Есть и полностью однопоточный режим:

--singleThreaded

Он пригодится для отладки, сравнения с TypeScript 6.0 и запуска в окружениях с ограниченными ресурсами.

Режим —watch тоже переписали

В TypeScript 7.0 заново реализовали режим наблюдения за изменениями файлов:

tsc --watch

За основу взяли подход из файлового наблюдателя Parcel и перенесли его на Go. Это сделано, чтобы не тащить отдельную C++-цепочку сборки.

Для больших репозиториев это не мелочь. Простой опрос файловой системы работает, но на проектах с тяжёлым node_modules быстро начинает съедать ресурсы. Новый наблюдатель должен лучше вести себя на разных платформах и стабильнее обрабатывать изменения в крупных проектах.

Что с редакторами

TypeScript 7.0 можно попробовать не только из командной строки. Для VS Code есть расширение TypeScript Native Preview, которое подключает новую реализацию в редакторе.

Новая версия использует протокол языкового сервера — Language Server Protocol, или LSP. Это важно не только для VS Code: такой подход проще переносить и в другие редакторы.

В последние месяцы команда закрывала пробелы в редакторной поддержке. В TypeScript 7.0 уже работают автоматические импорты, подсказки типов прямо в коде, переходы к определениям, подсветка, сортировка импортов и удаление неиспользуемых импортов. По словам команды, новый языковой сервер уже показывает меньше сбоев команд, чем TypeScript 6.0.

Но с программным API пока осторожно

Самая важная оговорка: у TypeScript 7.0 пока нет стабильного программного API. Его обещают не раньше TypeScript 7.1.

Это касается инструментов, которые напрямую завязаны на API TypeScript: линтеров, анализаторов, плагинов и другой инфраструктуры вокруг компилятора. Поэтому на переходный период команда предлагает держать рядом TypeScript 6.0 и TypeScript 7.0.

Для этого опубликован пакет:

@typescript/typescript6

Он даёт исполняемый файл tsc6 и переэкспортирует API TypeScript 6.0. Так можно собирать проект новым tsc, а инструменты, которым нужен старый API, оставить на шестой версии.

Один из вариантов установки через npm-алиасы:

npm install -D typescript@npm:@typescript/typescript6

Если нужно держать обе версии в одном проекте, зависимости можно явно развести в package.json:

{  "devDependencies": {    "typescript": "npm:@typescript/typescript6@^6.0.0",    "typescript-7": "npm:typescript@rc"  }}

Что может сломаться при переходе

TypeScript 7.0 подтягивает новые значения по умолчанию и ограничения из TypeScript 6.0. Поэтому часть проблем при миграции может быть связана не с Go-реализацией, а с уже изменившимися правилами компилятора.

Из заметного:

  • strict теперь включён по умолчанию;

  • module по умолчанию равен esnext;

  • noUncheckedSideEffectImports включён по умолчанию;

  • stableTypeOrdering включён по умолчанию и больше не отключается;

  • rootDir по умолчанию указывает на ./;

  • types по умолчанию равен пустому массиву.

Особенно легко споткнуться о rootDir и types.

Например, если tsconfig.json лежит выше src, лучше явно указать корневую папку исходников:

{  "compilerOptions": {    "rootDir": "./src"  },  "include": ["./src"]}

А если проект зависит от глобальных объявлений типов, их тоже стоит перечислить явно:

{  "compilerOptions": {    "types": ["node", "jest"]  }}

Часть старых настроек больше не поддерживается. Например, нельзя использовать target: es5, moduleResolution: node/node10, moduleResolution: classic, а также выставлять esModuleInterop и allowSyntheticDefaultImports в false.

Что изменилось для JavaScript-проектов

В TypeScript 7.0 переработали анализ JavaScript-файлов. Теперь он ближе к тому, как компилятор работает с .ts-файлами.

Это может быть заметно в проектах, где типизация JavaScript держится на JSDoc. Некоторые старые JSDoc-паттерны и синтаксис в стиле Closure больше не поддерживаются. Поэтому таким проектам лучше прогнать RC на реальном коде, а не ограничиваться небольшой проверкой на примере.

Есть и более тонкое изменение: TypeScript 7.0 иначе работает с Unicode в шаблонных строковых типах. Теперь поведение лучше соответствует реальным символам, а не только UTF-16-кодовым единицам. Обычные проекты вряд ли это заметят, но редкие утилиты типов, которые специально опирались на старое поведение, могут потребовать правок.

Что дальше

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

Для небольших проектов переход может оказаться почти незаметным: поставили, собрали, сравнили время. Для крупных кодовых баз всё интереснее. Там стоит отдельно проверить CI, потребление памяти, работу редактора и совместимость инструментов, которые используют API TypeScript.

TypeScript 7.0 выглядит не как обычное обновление компилятора, а как смена технического фундамента. Язык остаётся тем же, но скорость проверки типов и поведение инструментов вокруг него могут заметно измениться.

Если хочется не только следить за релизами, но и разбираться в смежных темах на практике, в дайджесте собрали бесплатные ИТ-уроки: про CI, Go, архитектуру, инфраструктуру, безопасность и разработку.

ссылка на оригинал статьи https://habr.com/ru/articles/1050634/