Команда JavaScript for Devs подготовила перевод большого апдейта от команды TypeScript. Разработчики рассказали, как идёт переписывание компилятора на нативный код, что уже работает в превью TypeScript 7, какие ограничения остаются и почему версия 6.0 станет последним релизом на JavaScript. Новый TypeScript обещает серьёзный рывок в скорости и стабильности — самое время понять, что нас ждёт.
В начале этого года команда TypeScript объявила, что мы переносим компилятор и language service на нативный код, чтобы добиться более высокой производительности, снизить потребление памяти и улучшить параллелизм. Этот проект (с кодовым названием Project Corsa, будущий «TypeScript 7.0») стал серьёзным вызовом, и за последние месяцы мы продвинулись очень далеко. Мы рады рассказать, на каком этапе находимся, и показать, насколько «настоящим» новый набор инструментов TypeScript стал уже сегодня.
У нас также есть новости о том, какой будет дальнейшая дорожная карта, и как мы расставляем приоритеты в работе над TypeScript 7.0, чтобы довести портирование до завершения.
Поддержка редакторов и Language Service
Для многих разработчиков переписывание проекта остаётся чем-то теоретическим вплоть до релиза. Но здесь всё иначе.
Нативные превью TypeScript уже сейчас быстрые, стабильные и удобные — в том числе прямо в редакторе.
Language service TypeScript (та самая часть, которая отвечает за поддержку TypeScript и JavaScript в вашем редакторе) — это ключевой участок работы при переносе на нативный код, и попробовать её очень просто. Вы можете установить последнюю версию из Visual Studio Code Marketplace — она обновляется каждый день.
Команда всё ещё переносит отдельные возможности и чинит мелкие баги, но основа, которая формирует привычный опыт работы с TypeScript в редакторе, уже на месте и работает отлично.
В том числе:
автодополнение кода (включая автоимпорты!)
переход к определению
переход к определению типа
переход к реализации
поиск всех упоминаний
переименование
всплывающие подсказки (Quick Info/Hover)
помощь с сигнатурами
форматирование
диапазоны выделения
Code Lenses
дерево вызовов
символы документа
быстрые исправления для отсутствующих импортов
Вы можете заметить несколько новых пунктов по сравнению с прошлым большим обновлением — автоимпорты, поиск всех упоминаний, переименование и другое. Мы понимаем, что именно этих возможностей многие разработчики ждали, и что их отсутствие мешало попробовать нативные превью. Теперь они реализованы и готовы к повседневной работе! Всё это работает в любых TypeScript- или JavaScript-проектах, включая проекты с project references.
Мы также переработали отдельные части language service, чтобы улучшить стабильность и задействовать параллелизм на общей памяти. Раньше некоторые команды сообщали, что опыт работы местами был «падучим», но терпели это ради скорости. Новая архитектура гораздо надёжнее и должна уверенно работать как на маленьких, так и на больших проектах.
Хотя нам ещё есть что переносить и полировать, вашей команде почти наверняка стоит попробовать нативные превью TypeScript. Вы получите более быстрое открытие проектов, меньшее потребление памяти и более отзывчивый интерфейс редактора.
Если что-то вас не устроит, расширение позволяет легко переключаться между встроенным в VS Code движком TypeScript и новым. Очень рекомендуем вам и вашей команде попробовать расширение с нативным превью для VS Code!
Компилятор
Компилятор TypeScript тоже значительно продвинулся в процессе переноса на нативный код. Как и наше расширение для VS Code, мы публикуем ночные превью-сборки нового компилятора под пакетом @typescript/native-preview. Установить его через npm можно так:
# local dev dependency
npm install -D @typescript/native-preview
# global install
npm install -g @typescript/native-preview
Этот пакет предоставляет команду tsgo, которая работает примерно так же, как и существующая команда tsc. Обе можно запускать параллельно.
Частый вопрос, который мы слышим: «Безопасно» ли использовать TypeScript 7 для проверки сборки? Другими словами — действительно ли он находит те же ошибки, что и TypeScript 5.9?
Ответ — уверенное «да». Проверка типов в TypeScript 7 практически полностью готова. Для понимания масштаба: у нас около 20 000 тестов компилятора, из которых примерно 6 000 выдают хотя бы одну ошибку в TypeScript 6.0. И во всех случаях, кроме 74, TypeScript 7 тоже выдаёт хотя бы одну ошибку. Оставшиеся 74 — это либо известные незавершённые участки (например, проверка синтаксиса регулярных выражений или ошибки isolatedDeclarations), либо ожидаемые изменения (депрекейты, новые значения по умолчанию и т. д.). Вы можете смело использовать TypeScript 7 уже сегодня, чтобы проверить свой проект на ошибки типов.
Помимо одношаговой проверки одного проекта, консольный компилятор тоже достиг почти полной функциональности. Возможности вроде --incremental, project references и --build теперь также перенесены и работают! Это значит, что большинство проектов уже могут попробовать нативное превью почти без изменений.
# Running tsc in --build mode...
tsc -b some.tsconfig.json --extendedDiagnostics
# Running the *new compiler* in --build mode...
tsgo -b some.tsconfig.json --extendedDiagnostics
И это не просто полный набор возможностей — они ещё и становятся существенно быстрее по сравнению с существующей реализацией в TypeScript 5.9 и ранее («Strada codebase»). Как мы уже рассказывали, дело не только в скорости нативного кода, но и в использовании параллелизма на общей памяти. Это значит, что TypeScript теперь умеет выполнять быстрые многопоточные сборки не только для одного проекта — он может собирать несколько проектов параллельно! В сочетании с нашей реализацией --incremental мы почти подошли к тому, чтобы сделать сборки TypeScript мгновенными при мелких изменениях в больших кодовых базах.
Напомним: даже без --incremental TypeScript 7 часто показывает почти десятикратное ускорение по сравнению с компилятором 6.0 на полном прогоне!
Проект |
tsc (6.0) |
tsgo (7.0) |
Delta |
Ускорение |
|---|---|---|---|---|
sentry |
133.08s |
16.25s |
116.84s |
8.19x |
vscode |
89.11s |
8.74s |
80.37s |
10.2x |
typeorm |
15.80s |
1.06s |
14.20s |
9.88x |
playwright |
9.30s |
1.24s |
8.07s |
7.51x |
Ожидаемые отличия от TypeScript 5.9
Есть несколько нюансов, о которых стоит знать при использовании нового компилятора. Многие из них — временные и будут устранены к финальному релизу 7.0, но некоторые связаны с долгосрочными решениями, направленными на улучшение работы с TypeScript по умолчанию. Обещание TypeScript 7.0 означает, что нам придётся серьёзно переключить фокус на новую кодовую базу, чтобы закрыть существующие пробелы и как можно быстрее дать разработчикам новый набор инструментов. Но для начала разберём текущие изменения и ограничения.
Совместимость с депрекациями
В TypeScript 7.0 будут удалены поведения и флаги, которые планируется задепрекейтить в TypeScript 6.0. Уже сейчас список будущих депрекейтов в 6.0 можно посмотреть в нашем ишью трекере. Некоторые заметные примеры:
--targetпо умолчанию будет выставлен на последний стабильный ECMAScript (например, es2025)--target es5будет удалён, минимально поддерживаемый — es2015--moduleResolution node10(a.k.a.node) будет удалён в пользуbundlerиnodenext
Список неполный, поэтому лучше сверяться с ишью трекером, чтобы быть в курсе актуального состояния. Если ваш проект зависит от каких-то из этих устаревших механизмов, возможно, потребуется обновить код или tsconfig.json, чтобы обеспечить совместимость с TypeScript 7.0.
Наша команда экспериментирует с инструментом ts5to6, который помогает автоматически обновлять tsconfig.json. Инструмент использует эвристики по extends и references, чтобы обновлять и другие проекты в монорепе. На данный момент он умеет обновлять только baseUrl и rootDir, но в будущем могут появиться дополнительные возможности.
npx @andrewbranch/ts5to6 --fixBaseUrl your-tsconfig-file-here.json
npx @andrewbranch/ts5to6 --fixRootDir your-tsconfig-file-here.json
Генерация JavaScript, --watch и API
Даже при готовности к 6.0 есть ситуации, когда новый компилятор пока нельзя просто взять и подменить.
Во-первых, конвейер генерации JavaScript ещё не полностью готов. Если вам не нужна генерация JS из TypeScript (например, вы используете Babel, esbuild или что-то другое), либо если вы таргетируете современные браузеры/рантаймы, то использовать tsgo в сборке можно уже сейчас. Но если вам нужно, чтобы TypeScript генерировал код под старые окружения, то поддержка даунлевел-компиляции пока реализована лишь до уровня es2021, и без поддержки компиляции декораторов. Мы планируем вернуть полноценную поддержку --target вплоть до es2015, но работа всё ещё продолжается.
Ещё один момент — новый режим --watch может быть менее эффективным, чем существующий компилятор TypeScript в некоторых сценариях. Иногда помогает обходное решение — использовать nodemon вместе с tsgo и флагом --incremental.
Наконец, Corsa/TypeScript 7.0 не будет поддерживать Strada API. Corsa API всё ещё в разработке, и стабильной интеграции для инструментов пока нет. Это означает, что любые инструменты — линтеры, форматтеры, IDE-расширения — которые зависят от Strada API, не будут совместимы с Corsa.
Обходное решение — держать пакеты typescript и @typescript/native-preview рядом и использовать API версий ≤6.0 для инструментов, которым он нужен, а tsgo — для проверки типов.
Проверка JavaScript и совместимость с JSDoc
Ещё один важный момент — поддержка проверки типов в JavaScript (частично основанная на аннотациях JSDoc) была переписана с нуля. В попытке упростить внутреннюю архитектуру мы убрали поддержку некоторых сложных и малоиспользуемых паттернов, которые раньше распознавались и анализировались. Например, TypeScript 7.0 больше не распознаёт теги @enum и @constructor.
Также мы убрали часть «ослабленных» правил проверки типов в JavaScript, таких как интерпретация:
Objectкакany,Stringкакstring,Fooкакtypeof Foo, если во втором случае это было бы корректно в TypeScript-файле,параметров с типами
any,unknownилиundefinedкак опциональных,и других.
Некоторые из этих изменений документируются здесь (список будет обновляться).
Это означает, что некоторые JavaScript-кодовые базы могут начать получать больше ошибок, чем раньше, и им потребуется корректировка, чтобы хорошо работать с новым компилятором. С другой стороны, мы считаем, что новая реализация более надёжная, лучше поддерживаемая и согласуется с типовой системой TypeScript.
Если вам кажется, что какое-то поведение должно работать иначе или что-то отсутствует в нашей поддержке проверки типов для JavaScript — пожалуйста, создайте ишью в нашем GitHub-репозитории.
Фокус на будущем
Когда мы начали переписывать TypeScript в прошлом году, было много неопределённостей. Вдохновит ли это сообщество? Сколько времени займёт стабилизация новой кодовой базы? Как быстро команды смогут перейти на новый набор инструментов? Какой уровень совместимости нам удастся обеспечить?
По всем направлениям нас ждало приятноe удивление. Нам удалось реализовать проверки типов с чрезвычайно высокой совместимостью. В итоге команды как внутри Microsoft, так и за её пределами сообщают, что смогли перейти на нативный компилятор почти без усилий. Стабильность растёт, и мы движемся к тому, чтобы завершить внедрение большинства возможностей language service к концу года. Многие команды уже используют Corsa в ежедневной работе без каких-либо блокирующих проблем.
С приближением релиза 6.0 нам нужно подумать, что будет дальше для JavaScript-кодовой базы. Изначально мы планировали продолжать работу над веткой 6.0 «пока TypeScript 7+ не достигнет достаточной зрелости и распространённости». Мы понимаем, что остаётся работа, необходимая для разблокировки ещё большего числа разработчиков (например, улучшение API), и что завершение разработки ветки Strada — нашего компилятора на JavaScript — лучший способ ускорить устранение этих препятствий. Чтобы как можно быстрее довести работу до конца, мы предпринимаем несколько шагов в рамках проекта Strada.
TypeScript 6.0 — последний релиз на базе JavaScript-кода
TypeScript 6.0 станет последним релизом, основанным на текущей TypeScript/JavaScript-кодовой базе. Иными словами, мы не планируем выпускать TypeScript 6.1, хотя в редких случаях возможны патч-версии (например, 6.0.1, 6.0.2).
Можно считать TypeScript 6.0 «переходным» релизом между ветками 5.9 и 7.0. Версия 6.0 задепрекейтит определённые возможности, чтобы согласовать поведение с 7.0, и при этом будет сильно совместима по части проверки типов.
Большинство кодовых баз, которым нужно специализированное поведение Strada на стороне редактора (например, плагины language service), сможет использовать 6.0 для работы в редакторе и 7.0 — для быстрых сборок из командной строки. Обратный вариант тоже возможен: разработчики могут использовать 7.0 для ускорения работы редактора, а 6.0 — для инструментов, зависящих от API TypeScript 6.0.
Дополнительные исправления после релиза 6.0 будут выходить только в формате патчей и исключительно в случаях:
проблем с безопасностью,
регрессий высокой серьёзности (то есть новых серьёзных багов, которых не было в 5.9),
критичных исправлений, связанных с совместимостью 6.0/7.0.
Как и раньше, патчи будут редкими и выпускаться только при необходимости.
Но прямо сейчас наша цель — обеспечить максимальную совместимость между 6.0 и 7.0. Мы значительно ужесточаем критерии того, какие открытые PR будут приниматься в ветку 6.0. Это вступает в силу уже сегодня, и означает, что большинству разработчиков стоит скорректировать ожидания относительно того, какие ишью будут решены в 6.0. Кроме того, авторам PR стоит учитывать, что мы крайне редко будем мержить изменения в 6.0 — наш фокус направлен на то, чтобы как можно быстрее довести 7.0 до полного соответствия и стабильности. Мы хотим быть полностью прозрачными, чтобы никто не тратил силы впустую и чтобы нам не приходилось переносить изменения между кодовыми базами.
«Обнуление» вопросов language service
Хотя основная логика проверки типов была перенесена почти без поведенческих изменений, с language service ситуация другая. Благодаря новой архитектуре большая часть кода, отвечающего за автодополнение, подсказки, навигацию и многое другое, была существенно переписана. Кроме того, TypeScript 7.0 теперь использует стандартный протокол LSP вместо кастомного протокола TSServer, поэтому поведение некоторых функций расширения TypeScript в VS Code могло измениться.
В результате многие баги или предложения, связанные с поведением language service, могут либо не воспроизводиться в ветке 7.0, либо потребуют «перезапуска обсуждения».
Проверять такие ишью вручную очень затратно, поэтому мы будем закрывать существующие вопросы, связанные с language service. Если вы столкнулись с проблемой, закрытой под меткой 7.0 LS Migration, пожалуйста, создайте новый ишью — но только после того, как убедитесь, что он воспроизводится в нативном ночном превью. Если же нужная возможность ещё не перенесена в 7.0, подождите, пока она появится, прежде чем подавать новую заявку.
Что дальше?
Когда мы представили нативные превью несколько месяцев назад, нам приходилось снижать ожидания относительно состояния проекта. Теперь мы можем с уверенностью сказать, что нативный опыт работы с TypeScript — реален, стабилен и готов к широкому использованию. Но обратная связь нам всё так же крайне важна.
Поэтому мы призываем вас установить нативное превью-расширение для VS Code, использовать компилятор @typescript/native-preview там, где это возможно, и попробовать его в своих проектах. Делитесь впечатлениями и создавайте ишью в нашем GitHub-репозитории — это поможет нам устранить проблемы и расставить приоритеты в дальнейшей работе.
Мы с огромным энтузиазмом смотрим в будущее TypeScript и не можем дождаться, когда TypeScript 7.0 окажется у вас в руках!
Продуктивной разработки!
Русскоязычное JavaScript сообщество

Друзья! Эту статью перевела команда «JavaScript for Devs» — сообщества, где мы делимся практическими кейсами, инструментами для разработчиков и свежими новостями из мира Frontend. Подписывайтесь, чтобы быть в курсе и ничего не упустить!