Вышел TypeScript 7: нативный компилятор на Go ускоряет сборку в 8, 12 раз

Вышел TypeScript 7: нативный компилятор на Go ускоряет сборку в 8, 12 раз

Команда TypeScript в Microsoft объявила о выходе TypeScript 7, полностью переписанного нативного компилятора на языке Go. Ещё в прошлом году команда анонсировала цель: сделать весь инструментарий TypeScript на порядок быстрее за счёт нативного кода и многопоточности с общей (разделяемой) памятью. Новый компилятор писали максимально точно по образцу старого: логику и структуру исходного кода сохранили, чтобы результаты работы старой версии (на TypeScript/JavaScript) и новой (на Go) совпадали и оставались совместимы. Итог, ускорение полной сборки обычно в 8, 12 раз.

Установка не отличается от предыдущих версий: команда npm install -D typescript ставит новый исполняемый файл tsc (запускается как npx tsc). Поддержка в редакторах работает через протокол языкового сервера (LSP): у VS Code появилось отдельное расширение для TypeScript 7, Visual Studio включает его автоматически в зависимости от настроек проекта, заявлена поддержка WebStorm и других современных редакторов, авторы советуют свериться с документацией конкретного редактора, так как переход везде может занять разное время.

Ускорение касается каждого этапа разработки: загрузки проекта в редакторе, поиска всех ссылок на символ, автодополнения, подсветки ошибок на лету и самой сборки, включая режим слежения за файлами (--watch). Показательный пример от команды: на кодовой базе VS Code время от открытия редактора до появления первой ошибки в файле раньше составляло около 17,5 секунды, а с TypeScript 7, менее 1,3 секунды, то есть более чем в 13 раз быстрее. При этом за время сборки TypeScript 7, как правило, потребляет меньше памяти, чем версия 6.

Релиз обкатывали не только штатным набором из десятков тысяч тестов, которые гоняются на каждый коммит, весь последний год компилятор тестировали на реальных крупных кодовых базах внутри Microsoft (команды Loop, Office, PowerBI, Teams, Xbox) и во внешних компаниях: Bloomberg, Canva, Figma, Google, Lattice, Linear, Miro, Notion, Sentry, Slack, Vanta, Vercel, VoidZero и других. Заново собранная тестовая инфраструктура прогоняет автоматические и оперативные проверки на реальных TypeScript- и JavaScript-проектах с GitHub, чтобы вылавливать регрессии в компиляторе и языковом сервисе. По данным команды, новый языковой сервер TypeScript 7.0 снизил число неудачных команд языкового сервера более чем на 80% и число падений (crash) сервера, более чем на 60% по сравнению с TypeScript 6.0.

Среди отзывов команд, уже перешедших на TypeScript 7: инженеры Slack сообщили, что новая версия избавила их от 40% времени ожидания в очереди слияний (merge queue) и сократила проверку типов в CI (система непрерывной интеграции) с примерно 7,5 до 1,25 минуты, раньше локальная разработка в редакторе была почти непригодной из-за долгой загрузки языкового сервера и команда полагалась на полную проверку типов в CI, а теперь та же кодовая база в редакторе загружается за несколько секунд. В Vanta сборка одного из крупнейших проектов ускорилась до 9 раз. Команда News Services в Microsoft сообщила об экономии 400 часов в месяц ожидания сборок в CI. Инженеры PowerBI ещё в прошлом году назвали работу с TypeScript 7 в редакторе «спасением» для своей кодовой базы и сделали её основной ещё до того, как в TypeScript 7 появилась функция переименования в VS Code. Команда Loop, работающая с большим монорепозиторием, назвала прежний опыт непригодным для их масштаба, а новый, «потрясающим». В Canva время до появления первой ошибки в редакторе сократилось примерно с 58 до 4,8 секунды.

Важная оговорка: сам TypeScript 7.0 выходит без собственного программного API для компилятора, новый (и другой) API обещан только в версии 7.1. Чтобы не ломать инструменты, которым нужен программный доступ к компилятору (например, typescript-eslint), команда выпустила пакет совместимости @typescript/typescript6. Он даёт исполняемый файл tsc6 (чтобы не конфликтовать с tsc из TypeScript 7) и повторно экспортирует API версии 6.0. Поскольку часть инструментов ожидает пакет typescript напрямую через зависимости, которые должны предоставляться извне (peer dependencies), команда рекомендует использовать npm-алиасы, например, npm install -D typescript@npm:@typescript/typescript6, либо прописать алиасы вручную в package.json, при необходимости добавив отдельный алиас, чтобы npx tsc по-прежнему указывал на TypeScript 7.

Ночные сборки, которые раньше распространялись отдельным пакетом @typescript/native-preview (более 8,5 млн скачиваний в неделю), теперь возвращаются под тегом next в обычном пакете typescript: npm install -D typescript@next.

TypeScript 7.0 распараллеливает разбор кода (parsing), проверку типов (type-checking) и генерацию файлов (emit); часть этапов, как разбор и генерация, параллелится легко, поэтому масштабирование на больших кодовых базах происходит почти без накладных расходов. Для настройки менее тривиальных этапов появились экспериментальные флаги --checkers и --builders, а флаг --singleThreaded полностью отключает параллелизм, пригодится для отладки или для сред с ограниченными ресурсами. Проверка типов по умолчанию использует 4 параллельных обработчика-воркера (настраивается флагом --checkers): каждый воркер обсчитывает файлы независимо, но при одинаковом наборе входных файлов деление между воркерами и результат всегда одинаковы. Больше воркеров обычно ускоряет сборку на многоядерных машинах, но повышает расход памяти; на CI-раннерах с малым числом ядер число воркеров, наоборот, стоит уменьшать, вплоть до --checkers 1 (по сути однопоточная проверка типов без дублирования работы). В редких случаях изменение числа --checkers может повлиять на порядок и итог проверки типов, поэтому команда советует фиксировать одно значение для всех окружений сборки. Похожим образом флаг --builders управляет числом параллельно собираемых проектов при сборке по ссылкам на проекты (project references) через --build, это особенно полезно для монорепозиториев с большим числом проектов.

Ключевые факты

  • TypeScript 7, нативный компилятор на Go, ускоряет полную сборку обычно в 8, 12 раз; на кодовой базе VS Code время до первой ошибки в файле сократилось с 17,5 до 1,3 секунды (более чем в 13 раз).
  • Новый языковой сервер снизил число неудачных команд более чем на 80% и число падений сервера, более чем на 60% относительно TypeScript 6.0; протестирован на кодовых базах Microsoft (Loop, Office, PowerBI, Teams, Xbox) и внешних компаний (Bloomberg, Canva, Figma, Google, Slack, Vanta, Vercel и др.).
  • Реальные результаты у пользователей: Slack сократил очередь слияний на 40% и проверку типов в CI с 7,5 до 1,25 минуты; Vanta ускорила сборку до 9 раз; Microsoft News Services экономит 400 часов CI в месяц; Canva сократила время до первой ошибки с 58 до 4,8 секунды.
  • TypeScript 7.0 выходит без программного API для компилятора (обещан в 7.1); для инструментов вроде typescript-eslint выпущен пакет совместимости @typescript/typescript6 с бинарником tsc6 и настройкой через npm-алиасы.
  • Появились экспериментальные флаги контроля параллелизма: --checkers (воркеры проверки типов, по умолчанию 4) и --builders (параллельная сборка проектов в монорепозиториях), а также --singleThreaded для полного отключения параллелизма.

Почему это важно

TypeScript годами был написан на самом себе (TypeScript/JavaScript), и на больших кодовых базах производительность компилятора и языкового сервера, автодополнение, проверка типов на лету, поиск ссылок, стала узким местом, особенно в монорепозиториях. Переход на нативный порт на Go при сохранении логики и структуры оригинального компилятора даёт кратный (8, 12x) прирост скорости без изменения кода самих проектов на TypeScript. Это не косметическая оптимизация: по свидетельствам команд вроде Slack и Loop, раньше работа языкового сервера в редакторе на больших кодовых базах была практически непригодной для использования, и команды полагались на проверку типов в CI, с TypeScript 7 локальная разработка снова стала комфортной.

Кому это важно

В первую очередь, фронтенд- и бэкенд-разработчикам на TypeScript и их тимлидам/DevOps-инженерам, которые отвечают за время сборки в CI. Особенно ощутимо для компаний с большими монорепозиториями, таких как Slack, Vanta, Canva, Figma, Notion, уже опробовавших TypeScript 7 в продакшене и получивших кратные ускорения. Также это важно для мейнтейнеров сопутствующих инструментов TS-экосистемы (линтеров, сборщиков, ESLint-плагинов вроде typescript-eslint), которым нужно синхронизировать поддержку между старым (6.0) и новым (7.0) программным API компилятора.

Как это применить

Установить можно как обычно, npm install -D typescript, дальше работает привычный tsc/npx tsc. В VS Code нужно поставить отдельное расширение для TypeScript 7, в Visual Studio поддержка включается автоматически, в других редакторах, сверьтесь с документацией (поддержка идёт через LSP). Нужны ночные сборки, ставьте typescript@next (отдельный пакет @typescript/native-preview для этого больше не нужен). Для тонкой настройки параллелизма используйте --checkers N (число воркеров проверки типов, по умолчанию 4, больше ядер и памяти позволяют поднять значение, для CI с ограниченными ресурсами его стоит понижать вплоть до 1) и --builders N (число параллельно собираемых проектов при --build, полезно для монорепозиториев); флаг --singleThreaded полностью отключает параллелизм для отладки. Если ваши инструменты (например, typescript-eslint) всё ещё требуют программного API компилятора, держите TypeScript 6 рядом через пакет @typescript/typescript6 (бинарник tsc6) и npm-алиасы в package.json.

Можно ли доверять

Это официальный анонс команды TypeScript в блоге Microsoft, а не независимая оценка, но заявления подкреплены конкретными измеримыми показателями (снижение числа отказов и падений языкового сервера на 80% и 60% соответственно, тайминги на реальных open-source кодовых базах) и именными цитатами инженеров компаний, которые уже используют TypeScript 7 в продакшене на своих реальных проектах (Slack, Vanta, Canva, PowerBI, Loop и другие), то есть это не только синтетические бенчмарки вендора, а результаты внешних команд. При этом отбор цитат и кейсов делала сама команда TypeScript, независимой проверки этих цифр в тексте нет, а часть результатов ожидаемо зависит от особенностей конкретного проекта: сама команда предупреждает, что результаты отличаются в зависимости от проекта и используемого железа.

Риски и подводные камни

TypeScript 7.0 выходит без программного API компилятора, плагины и инструменты, зависящие от него (например, typescript-eslint), нужно временно держать на TypeScript 6 через дополнительный пакет и npm-алиасы, а это лишний шаг миграции; полноценный новый API обещан только в версии 7.1. Увеличение числа воркеров через --checkers/--builders ускоряет сборку, но повышает расход памяти, на CI с ограниченными ресурсами это может стать проблемой, если значения не подобраны под конкретную машину. Команда также предупреждает, что в редких случаях изменение числа --checkers может повлиять на порядок и итоговый результат проверки типов, поэтому для стабильности стоит фиксировать одинаковое значение во всех окружениях сборки. Наконец, поддержка в редакторах зависит от актуальности расширений и версий LSP, переход может быть не мгновенным для менее популярных редакторов.

«Инженеры Slack рассказали нам, что TypeScript 7 избавил их от 40% времени в очереди слияний и сократил время проверки типов в CI с примерно 7,5 минуты до 1,25 минуты.»

— инженеры Slack, в анонсе TypeScript 7 (Microsoft DevBlogs)