Команда TypeScript сообщила 16 августа о выпуске предварительной версии (release candidate) TypeScript 3.6. В течение нескольких недель команда планирует стабилизировать предварительную версию. После этого TypeScript 3.6 выйдет официально.
Релиз кандидат доступен на NuGet. Также его можно установить через npm.
npm install -g typescript@rc
Есть сборки для Visual Studio, Visual Studio Code и Sublime Text.
Давайте посмотрим, какие возможности предлагает TypeScript 3.6.
Строгие генераторы
В новой версии TypeScript предусмотрена строгая проверка функций итераторов и генераторов. В ранних версиях пользователи генераторов не могли определить, было ли значение возвращено из генератора или определено.
Также генераторы ожидали, что типом yield
по умолчанию является any
.
TypeScript 3.6 ожидает, что в первом примере curr.value
имеет тип string
. Это возможно благодаря изменениям в определении типов в Iterator
и IteratorResult
. Также появился новый тип для представления генераторов: Generator
.
Iterator
в TypeScript 3.6 позволяет пользователям указывать тип принимаемых и возвращаемых данных, а также тип данных, которых принимает next
.
Новый тип Generator
всегда итерабельный, также у него всегда есть методы return
и throw
.
TypeScript 3.6 конвертирует IteratorResult
в различаемое объединение. Это позволяет определять разницу между получаемыми и возвращаемыми данными.
В TypeScript 3.6 используется yield
в теле функции-генератора. Это позволяет корректно представлять данные, которые передаются в генератор в результате вызова next()
.
Также в TypeScript 3.6 можно явно указывать тип данных, полученных из yield expression
. В примере ниже next()
можно выбрать только с типом данных boolean
. В зависимости от значения done
, value
может быть строкой или числом.
Детали можно найти в пулреквесте.
Более точный оператор Array Spread
До появления стандарта ES-2015 в циклах for/of
или спред-операторах массивов были довольно неудобные emit
’ы. Поэтому в TypeScript используется более простой дефолтный emit
, который поддерживает только массивы. Также он поддерживает итерацию других типов данных с флагом --downlevelIteration
. При использовании этого флага код получается более точным, но менее лаконичным.
Параметр --downlevelIteration
в новой версии исключён, так как большинство пользователей пользуются итерацией по массивам. Тем не менее emit
, который поддерживает только массивы, работает по-другому в некоторых пограничных случаях.
Обратите внимание на пример ниже.
Он эквивалентен массиву из следующего примера.
Однако TypeScript трансформирует его в такой код.
В то же время Array(5)
создаёт массив с длинной 5, но без определённых элементов.
При использовании метода slice()
TypeScript создаёт массив, в котором значения не определены, но у которого есть индексы.
Этот нюанс может показаться несущественным, но он доставляет неудобства специалистам. Поэтому в TypeScript 3.6 представлен новый инструмент __spreadArrays
. Подробную информацию о нём можно найти в соответствующем пулреквесте.
Более удобные промисы
Промисы — самый распространённый способ работы с асинхронными данными. Однако использование API, ориентированных на промисы, доставляет разработчикам неудобства. В TypeScript 3.6 улучшена работа с неправильно обрабатываемыми промисами.
Например, специалисты иногда забывают использовать .then()
или await
перед передачей промисов в другую функцию. Новая версия TypeScript сообщает об этой ошибке и предлагает пользователю использовать await
.
Также разработчики иногда пытаются получить доступ к методу до использования await
или .then()
. Пример ниже показывает, как TypeScript 3.6 реагирует на эту ошибку.
То есть даже если пользователь не использует await
, он получает дополнительную информацию, которая позволяет исправить ошибку.
Также появилась опция быстрого исправления описанной выше ошибки (см. иллюстрацию).
Подробности смотрите в соответствующем issue.
Улучшена поддержка юникода в идентификаторах
В релиз кандидате TypeScript 3.6 улучшена поддержка юникода в идентификаторах. Пример ниже.
Поддержка import.meta
в System.js
В TypeScript 3.6 включена поддержка трансформации import.meta
в context.meta
. Нагляднее в коде.
Методы доступа get
и set
можно использовать в окружающем контексте
В более ранних версиях методы доступа get
и set
нельзя было использовать в окружающем контексте (например, в declare class
). Теперь разработчики могут пользоваться геттерами и сеттерами.
Окружающие классы и функции можно объединять
В ранних версиях TypeScript попытка объединить классы и функции приводила к ошибке в любом случае. В предварительной версии TypeScript 3.6 классы и функции с модификатором declare
можно объединять.
Это позволяет использовать такой код.
Раньше пришлось бы писать так.
Благодаря этому можно использовать вызываемый конструктор, что обеспечивает объединение пространства имён. Подробности смотрите в оригинальном пулреквексте.
API теперь поддерживают --build
и --incremental
Начиная с версии 3.0 в TypeScript включена поддержка --build
, а в версии 3.4 добавлена поддержка --incremental
. Эти флаги позволяют гибко структурировать проекты и ускоряют разработку. К сожалению, --build
и --incremental
не работали со сторонними инструментами, например, Gulp или Webpack. В TypeScript 3.6 данная возможность появилась.
Чтобы создавать сборки с --incremental
, разработчики могут использовать API createIncrementalProgram
и createIncrementalCompilerHost
. Новая функция readBuilderProgram
позволяет использовать файлы из .tsbuildinfo
, сгенерированные указанными API.
Подробности смотрите в пулреквесте.
Решена проблема точки с запятой
Редакторы и среды разработки типа Visual Studio Code и Visual Studio автоматически предлагают исправления и дополнения. Это реализовано с помощью TypeScript. Старые версии TypeScript автоматически добавляли точку с запятой в конце каждого выражения. Это неудобно для части пользователей, так как в некоторых стайлгайдах использование точки с запятой не предустматривается.
Новая версия TypeScript интеллектуально решает проблему точек с запятыми. Если в вашем проекте они используются, редактор их добавляет в код. В противном случае точки с запятыми не добавляются.
Детали в пулреквесте.
Умный синтаксис автоимпорта
Старые версии TypeSript по умолчанию используют для автоимпорта синтаксис ECMAScript. Это неприемлемо для части проектов TypeScript с определёнными настройками компилятора, а также для проектов Node с использованием нативного JavaScript, где используется require
.
TypeScript 3.6 интеллектуально решает проблему автоимпортов. Для этого он изучает существующие импорты, которые уже используются в проекте.
Подробнее в пулреквесте.
Методы со строковым именем constructor
становятся конструктором
Методы с названием constructor
считаются конструктором независимо от того, как они объявляются: с помощью идентификатора или строкового имени.
Важное исключение — вычисляемые значения остаются методами.
class D {
["constructor"]() {
console.log("Я метод, а не конструктор!");
}
}
Обновления DOM
Ниже несколько важных изменений.
- Тип глобального объекта
window
изменился сWindow
наWindow & typeof globalThis
. - Вместо
GlobalFetch
используетсяWindowOrWorkerGlobalScope
. - Вместо контекста
experimental-webgl
используетсяwebgl
илиwebgl2
.
Комментарии JSDoc не объединяются
В проектах JavaScript TypeScript обращается к комментариям JSDoc, чтобы определить объявленный типы.
Ключевые слова не могут содержать избегающие последовательности
В релиз кандидате вводится запрет на использование избегающих последовательностей в ключевых словах.
Что дальше
Команда TypeScript ждёт обратную связь по релиз кандидату TypeScript 3.6. Полученные данные помогут выпустить официальную версию TypeScript.
Адаптированный перевод статьи Announcing TypeScript 3.6 RC. Мнение администрации «Хекслета» может не совпадать с мнением автора оригинальной публикации.
Дмитрий Дементий
6 лет назад