Что будет переносить 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 и "Символ".
Компилятор не будет добавлять полифилл, вам нужно добавить его, а затем сообщить компилятору, что он там есть.

Другие вопросы по тегам