Что будет переносить Typescript при нацеливании на ES5 / ES3?
Я пытаюсь понять, когда компилятор Typescript будет транслировать код, чтобы сделать его совместимым с моей указанной целевой версией ECMAScript (ES5 или ES3).
Например, TSC будет проходить for(var int of intArray)
хорошо, но это не проходит Number.isInteger()
(это особенность ES6, согласно w3schools).
Number.isInteger()
не поддерживается в IE < 11.0, так что это проблема. Visual Studio (и код VS) не предоставляют предупреждений о несовместимости и не передаются.
Что я могу ожидать, чтобы быть перенесенным, а что нет? Сначала я ожидал, что все будет передано, так что мне не придется отслеживать такие вещи, но это не так.
2 ответа
TypeScript переносится, но не заполняется. Таким образом, один из способов думать о том, что все, что не является допустимым синтаксисом в вашем target
будет перенесен в правильный синтаксис. Например, при использовании class
Ключевое слово с вашей целью установлено ES5
, это перенесет это:
class Greeter {
}
к этому:
var Greeter = /** @class */ (function () {
function Greeter() {
}
return Greeter;
}());
(Вы можете больше поиграть с этим здесь.)
С другой стороны, он не добавляет недостающую функциональность, которую вам придется самостоятельно заполнять. Number.isInteger()
является действительным ES5
синтаксис, это просто не функциональность, которая существует в ES5
, Вы можете заполнить это самостоятельно, импортировав babel-polyfill
(который использует core-js
под капотом) или с помощью службы, как polyfill.io.
Примечание: не путайте lib
вариант с полифилами. Это не функции polyfill. Он просто указывает TypeScript действовать так, как будто функции из этих версий ES присутствуют, поэтому он проверяет их соответствующим образом. Вам по-прежнему нужно самостоятельно обрабатывать часть полифилла для браузеров, которые вы поддерживаете. Если вы не укажете соответствующий lib
s, TypeScript будет жаловаться, что не знает, что Number.isInteger()
представляет собой.
Я не знаю исчерпывающего списка функций, которые переносит TypeScript, но вы можете увидеть таблицу для TypeScript + core-js
полифилы здесь. Подробнее о полифиллах и транспиляции читайте здесь.
Компилятор поддерживает функции, основанные на той библиотеке, которую вы указали использовать.
Есть два способа контролировать, какую библиотеку будет использовать компилятор, используя target
а также lib
параметры компилятора.
Как написано в приведенной выше ссылке:
Если --lib не указан, будет добавлена библиотека по умолчанию. Используемая библиотека по умолчанию:
► Для --target ES5: DOM, ES5, ScriptHost
► Для -target ES6: DOM,ES6,DOM.Iterable,ScriptHost
Все разные библиотеки являются частью проекта.
Если вы нацеливаетесь es3
или же es5
тогда вы не можете использовать Number.isInteger()
как это (как вы сказали) es6
особенность.
Если у вас есть полифайл для этого, вы все равно можете настроить таргетинг es5
с es6
Lib:
--target es5 --lib DOM,ES6,ScriptHost
Или вы можете просто скопировать определение для lib.es6.d.ts:
interface NumberConstructor {
isInteger(number: number): boolean;
}
Причина, по которой вы можете использовать такие вещи, как let
, const
, for/of
Независимо от цели, компилятор знает, как создать эквивалентный код, даже если эта функция не поддерживается для выбранной цели.
Например:
const arr = [1, 2, 3];
for (let num of arr) {}
Составлен в:
var arr = [1, 2, 3];
for (var _i = 0, arr_1 = arr; _i < arr_1.length; _i++) {
var num = arr_1[_i];
}
Если цель не указана.
Как видите, const
а также let
превращаются в var
с, и for/in
превращается в обычный for
,
Number.isInteger()
это что-то другое, это функциональность, которая не существует в определенных целях, таких как Promise
и "Символ".
Компилятор не будет добавлять полифилл, вам нужно добавить его, а затем сообщить компилятору, что он там есть.