История немного сложнее, и мы должны начать с того, что разделим ее на две части: функции языка и функции времени выполнения.
Особенности языка ES
Когда мы говорим о функциях языка, мы имеем в виду изменения в основном синтаксисе языка JavaScript. Например, ES 2015
добавляет поддержку классов, функций стрелок (=>
) и for-of
итерации
Typescript пытается реализовать все предложения по стабильным языковым возможностям как можно скорее и компилирует их до версии ES, указанной в опции target
для компилятора. Таким образом, это означает, что если у вас есть новейший компилятор Typescript, который добавляет поддержку новой новой языковой функции ES 2019
, вы сможете скомпилировать его вплоть до ES3
. Typescript выдаст код, необходимый для работы таких функций в любой версии ES, на которую вы ориентируетесь.
И теперь вы можете увидеть это в действии. Если вы нацелены на ES5
, функции стрелок скомпилированы в обычные function
s и используют локальную переменную _this
для захвата this
. Классы компилируются в функцию и соответствующие поля в наборе prototype
.
Возможности ES Runtime
В дополнение к языковым функциям у нас есть определенные функции времени выполнения, которые описывают, какие встроенные типы объектов доступны, и какие методы и поля имеют эти объекты времени выполнения. Примерами новых типов объектов в последних версиях ES
могут быть Promise
или Proxy
.
Typescript не предоставляет полизаполнения для таких функций, если среда выполнения не предлагает поддержки для них, вам потребуется собственная реализация полизаполнения, если вы хотите их использовать.
Однако Typescript должен знать, какие встроенные объекты существуют во время выполнения, и каковы их методы / поля. Именно здесь появляется опция lib
. Она позволяет вам указать, как будет выглядеть среда выполнения.
Таким образом, вы можете, например, нацелить es5
, но указать, что среда выполнения будет иметь все встроенные объекты в соответствии со стандартом es2015
(некоторые могут быть реализованы самой средой выполнения, другие могут быть добавлены вами через поли-заливки)
Пересечение двух
Разделение, приведенное выше, является упрощением, поскольку некоторые функции языка зависят от существования определенных встроенных объектов и методов.
Например, языковая функция async/await
зависит от наличия обещаний. Поэтому, если вы используете async/await
и target es5
, вы получите ошибку, что конструктор Promise
не существует. Если вы нацелились на es5
, но указали lib: [ 'es2015', 'dom' ]
, вы больше не получите сообщение об ошибке, так как сказали компилятору, что даже если вы хотите выполнить компиляцию до es5
, во время выполнения конструктор Promise
будет существовать согласно es2015
спецификация времени выполнения, представленная в этой конкретной библиотеке (не проблема компилятора, как это произойдет, полизаполнения или встроенное поведение во время выполнения).
Обычно, если такая зависимость существует, компилятор машинописного текста выдаст ошибку, что некоторые типы отсутствуют, и вы можете обновить вашу библиотеку или изменить вашу цель (что изменит используемые библиотеки по умолчанию), но вы должны будете убедиться, что среда выполнения имеет необходимую поддержку.
Исключения
Не всегда возможно выполнить детальную компиляцию языковых функций вплоть до es3
(либо из-за отсутствующих функций во время выполнения, либо просто из-за высокой стоимости реализации функции, что не делает ее приоритетной для команда компилятора). Примером могут быть методы доступа к свойству (get
/ set
) при таргетинге на es3
, что не поддерживается. Однако компилятор должен предупредить вас, если вы используете неподдерживаемую языковую функцию / целевую комбинацию.