Обзор TypeScript 6

• typescript

Вступление

Совсем недавно вышел свежий TypeScript 6. TypeScript – де-факто стандарт для современной веб-разработки, и он используется в подавляющем большинстве новых проектов. Нельзя сказать, что JavaScript сам по себе устарел, нет, но для современного разработчика знать TypeScript хотя бы на каком-то уровне – минимальная необходимость.

Новый “мажорный” релиз не обладает миллионом новых возможностей или улучшений (но они есть), вместо этого он является обновлённым фундаментом и генеральной уборкой, которая требовалась годами. Не всё полечено (мне до сих пор не нравится логика skipLibCheck), но подобного объёма работ по пересмотру не было ни в одном предыдущем “мажорном” релизе.

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

Новые тайпинги

Добавилась поддержка es2025 в target и lib. Это добавляет ряд новых апи: методы итераторов, RegExp.escape, Promise.try, новые методы Set, новые upsert методы.

Но лично я ждал Intl.DurationFormat, который работает в браузерах уже несколько лет:

Intl.DurationFormat
129
136
16.4

Ну и, конечно, Temporal. Новое, мощное апи, а теперь ещё и с готовыми тайпингами. Давно пора!

Для использования новых тайпингов может потребоваться lib = ["esnext"] и target = esnext.

Новые дефолты

Для начала хочется процитировать авторов, какими принципами они руководствовались:

  • За время существования TypeScript разработка изменилась, и новый релиз призван этому соответствовать
  • В проектах всё чаще включают более строгие режимы TypeScript, чтобы ловить больше проблем
  • Все возможности должны быть не в ущерб скорости. И дефолты тоже

Теперь пройдёмся по самим изменениям:

Строгий режим (strict) включён по дефолту. Нестрогий режим всё ещё доступен по "strict": false.

types теперь по дефолту пустой массив []. Чтобы вернуть старое поведение, можно использовать ["*"]. Но помните: вполне возможно, в вашей директории node_modules/@types лежит куча всего, что не требуется вашему проекту! Новая версия TypeScript – хороший повод пересмотреть этот список и оставить, например, только ["node"] и ещё пару пакетов.

module теперь по умолчанию равен esnext, а target теперь равен последней поддерживаемой версии EcmaScript (в TypeScript 6 – es2025). Конечно, всё ещё можно выбрать старые значения, если это необходимо.

rootDir теперь по умолчанию равен директории, в которой лежит tsconfig.json, а не вычисляется, исходя из файлов вашего проекта (до этого брался наибольший общий префикс). Не уверен, как много проектов это заденет, но вручную выставить нужное значение не очень сложно.

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

Устаревшие возможности

Целая куча возможностей теперь “устаревшие”, и в следующей мажорной версии (которая ожидается в этом году) их поддержки уже не будет.

target = es5, downlevelIteration, amd, umd, systemjs, moduleResolution = node10 / classic устарели. По факту, они создавались в сильно другое время, а количество проектов, их использующих, падает со временем. Если ваш проект – один из них, рассмотрите обновление конфига / логику сборки, или в какой-то момент ваш проект будет становиться всё большим и большим “легаси”.

baseUrl теперь тоже устаревший. Обычно он появлялся в проектах, когда разработчики добавляли алиасы через paths, однако сейчас baseUrl уже работает и без paths. baseUrl также добавлял возможность импортировать файлы из указанной директории без какого-либо пути! Очень спорная практика, и хорошо, что от неё отказываются.

Но я вижу потенциальную проблему в удалении baseUrl. Если разработчики ещё более-менее спокойно обновят свои проекты на конфиг без baseUrl и тайпинги заработают, то вот с инструментами будет сложнее. Это могут быть и плагины для сборки, которые реализуют алиасы, это может быть playwright, который полагался на baseUrl, какой-нибудь ESLint-плагин или инструмент для построения дерева зависимостей вашего проекта. Боюсь, тут потребуется значительное время, чтобы все нужные инструменты адаптировались к этому.

outFile устарел. Для тех, кто полагался на него для сборки (например, для публикации npm-пакета), придётся придумывать что-то новое на замену. И я полностью понимаю авторов TypeScript: они решили сосредоточиться на своих задачах. Есть куча инструментов для сборки, но кому-то придётся потратить время на переезд.

Обновляемся?

TypeScript 6 – промежуточный релиз перед TypeScript 7. Он призван упростить переход на следующую версию, которую пилят на языке Go. Главная фича TS 7 – скорость, и обещают ускорение в сложных проектах в условные 9 раз (сильно зависит от самого проекта).

В то же время, в 6 релизе нет очень мощных фичей, ради которых нужно было бы бежать обновляться прямо сегодня. Если вашему проекту не нужны новые тайпинги, то обновление спокойно ждёт, и может быть положено в беклог. Только помните, что чем больше ждать, тем сложнее будет переходить на TypeScript 7 (а переходить на него вы, скорее всего, захотите).

Кому не нужно обновляться

Если ваш проект сильно завязан инструменты или фреймворки, которые ещё не поддержали TypeScript 6, то есть вероятность, что у вас просто это сделать не получится. Например, данный блог написан на SvelteKit, и на момент написания статьи версия с поддержкой TypeScript 6 ещё не вышла. И дело даже не в прописанных зависимостях в package.json, которые можно обойти оверрайдами. С TypeScript 6 проект вообще не собирается.

Остаётся ждать обновлений и поддержки во всех необходимых инструментах.

Итого

TypeScript 6 – хороший, большой мажорный релиз, который не выглядит таковым. Заложите время, попробуйте обновиться (если все ваши зависимости уже поддерживают его) – и это будет хорошим подспорьем для TS 7.

Обновились и всё завелось? Отлично, теперь можно попробовать превью версию TS 7. Промежуточных “минорных” релизов не запланировано, следующая остановка – сразу мажорный релиз и переезд.

Ну а для новых проектов “будущего” TS 6 – хороший фундамент. Главное – переждать немного несостыковки между инструментами.

Обсудить в Telegram

Почитать ещё посты

  • Type Branding и Type Flavoring
  • Зачем нужен режим совместимости WebGPU?
  • Проблемы, которые Anchor Positioning не должен был решить
  • shape(): фигуры для всех браузеров
  • color-mix() широко доступна