Зачем нужен полифилл ES7 / array, несмотря на то, что для цели tsconfig установлено значение ES5

У меня в файлеtsconfig.json есть следующие настройки. Я добавил "es2017", чтобы использовать Array.includes .:

{
  "compilerOptions": {
    "lib": [
      "es6",
      "es2017",
      "dom"
    ],
    "module": "es6",
    "target": "es5"
  }
}

Теперь я понял, что мне нужно добавить import 'core-js/es7/array'; к polyfills.ts, чтобы использовать Array.includes также и для Internet Explorer 11. target в tsconfig.json установлен на es5, что не имеет Array.includes.

Зачем мне добавлять полифилл?


person BuZZ-dEE    schedule 23.05.2019    source источник
comment
Целевой объект в tsconfig.json установлен на es5, у которого нет Array.includes. Разве вы сами не отвечаете на вопрос?   -  person    schedule 23.05.2019
comment
Нет, подумал я, если у меня "es2017" в lib, я могу использовать "es2017" функции, которые передаются на цель "es5". Поскольку Array.includes отсутствует в "es5", он переносится в Array.indexOf => 0 или что-то еще.   -  person BuZZ-dEE    schedule 23.05.2019
comment
да, но вы сами это сказали, вы ориентируетесь на ES5. Это означает, что вам нужны полифиллы, чтобы он работал. Компилятор не знает полифилов из коробки, вы должны импортировать их, чтобы он мог их импортировать. По крайней мере, я так понял ...   -  person    schedule 23.05.2019
comment
Почему мне не нужен полифилл в Firefox или Chrome? Если target установлен в es5, что затем генерирует транспилятор Typescript, потому что Array.includes не находится в es5?   -  person BuZZ-dEE    schedule 23.05.2019
comment
Он генерирует его с помощью полифилла!   -  person    schedule 23.05.2019
comment
Возможный дубликат Использование последних функций JavaScript в TypeScript, например ES2018   -  person jcalz    schedule 23.05.2019
comment
Вам не нужен полифилл в Firefox или Chrome, потому что в их средах выполнения есть рассматриваемый метод. Они просто запускают ту версию ECMAScript, которую они поддерживают; у них нет причин выдавать ошибку времени выполнения при задании [1,2,3].includes(0), поскольку браузеры даже не знают о целевой версии вашего кода TypeScript.   -  person jcalz    schedule 23.05.2019


Ответы (1)


TypeScript не выполняет автоматическое заполнение кода кодом. Официальная причина соответствующей проблемы GitHub, похоже, заключается в том, как сказал @RyanCavanaugh :

Компилятор пытается выяснить, какие методы [ES20XX] вам нужны, где их генерировать и когда, с элементами управления для людей, которые не хотят генерировать полифиллы, и способы изменить, где они polyfills происходят из и т.д., это большой беспорядок, который не оправдывается потенциальными выгодами от простого включения обычной библиотеки полифиллов [ES20XX] в контекст вашего скрипта.

И, как упоминалось в этой проблеме, создание кода среды выполнения - это нецелевое TypeScript:

[Не цель №] 6. Предоставьте дополнительные функции времени выполнения или библиотеки. Вместо этого используйте TypeScript для описания существующих библиотек.


Я предполагаю, что некоторая путаница возникает из-за того, что TypeScript делает нижний уровень некоторые языковые функции при нацеливании на более ранние версии EcmaScript. Главный критерий, используемый при определении того, будет ли функция выводиться в виде кода с пониженным уровнем или требуется ли для нее полифил, - это синтаксис:

Если новая языковая функция синтаксически недопустима в целевой версии, то она будет либо понижена, либо вы получите предупреждение во время компиляции. Вы не можете заполнить неверный синтаксис полифилом. Например, class Foo {} не является и не может быть допустимым кодом ES5 ... поэтому он будет преобразован в функцию-конструктор вместо этого при нацеливании на ES5.

Если, с другой стороны, языковая функция синтаксически допустима в целевой версии, она будет выдана как есть, без предупреждения. Итак, [1,2,3].includes(0) - это совершенно правильный код ES5 с точки зрения синтаксиса. Если предположить, что кто-то добавит Array.prototype.includes метод в движок ES5, он будет работать даже во время выполнения. Таким образом, он излучается как есть. Обратите внимание: когда вы включаете es2017 в параметры lib компилятора, вы сообщаете TypeScript, что среда выполнения будет поддерживать типизацию ES2017, и поэтому предупреждения во время компиляции не выводятся. Добавление библиотек набора текста ничего не делает с самой средой выполнения ... поэтому вы несете ответственность за полифиллинг / шиммирование всего, что вам нужно. С точки зрения компилятора, он не может справиться с ситуацией, когда вы солгали ему о том, какие методы существуют во время выполнения. Очевидно, что это не слишком утешит тех, кто разочарован ошибкой во время выполнения.

Ну да ладно, я думаю, это то, что есть.


Надеюсь, это поможет. Удачи!

person jcalz    schedule 23.05.2019
comment
Как отсканировать собственный код, чтобы узнать, какие библиотеки полифиллов вам нужны? : D - person mesqueeb; 29.07.2020
comment
@mesqueeb С опозданием на несколько месяцев, но правильная установка параметра компилятора lib приведет к ошибкам для любых методов, которые вы попытаетесь использовать, которых нет в версии, предназначенной для указанных библиотек. Таким образом, это был бы способ выяснить, что вам нужно для полифила: установите для lib самую низкую доступную версию, отметьте, какие ошибки возникают, и выполните полифил. - person KRyan; 11.10.2020