Why is ES7/array polyfill needed despite the tsconfig target is set to ES5

眉间皱痕 提交于 2019-12-10 10:14:28

问题


I have the following settings in thetsconfig.json. I added "es2017" to use Array.includes.:

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

Now, I realized, that I have to add import 'core-js/es7/array'; to the polyfills.ts, to use Array.includes also for the Internet Explorer 11. The target in the tsconfig.json is set to es5, which does not have Array.includes.

Why do I need to add the polyfill?


回答1:


TypeScript does not auto-polyfill code. The "official" reason from the relevant GitHub issue seems to be, as @RyanCavanaugh said:

Having the compiler try to figure out which [ES20XX] methods you need, and where to emit them, and when, with controls for people who don't want the polyfills emitted, and ways to change where those polyfills come from, etc, is a big mess that isn't justified by the potential gains over simply including a normal [ES20XX] polyfill library in your script context.

And, as it's mentioned in that issue, emitting runtime code is a non-goal of TypeScript:

[Non-Goal #]6. Provide additional runtime functionality or libraries. Instead, use TypeScript to describe existing libraries.


I'm guessing that some of the confusion comes from the fact that for some language features, TypeScript does downlevel some language features when targeting earlier EcmaScript versions. The main criterion used when determining if a feature will be emitted as downleveled code or whether it needs a polyfill is syntax:

If the new language feature is syntactically invalid in the targeted version, then it will either be downleveled or you will get a compile time warning. You can't polyfill invalid syntax. For example, class Foo {} is not and cannot be valid ES5 code... so it will be converted into a constructor function instead when targeting ES5.

If, on the other hand, the language feature is syntactically valid in the targeted version, it will be emitted as-is with no warning. So [1,2,3].includes(0) is perfectly valid ES5 code in terms of syntax. Assuming that someone adds an Array.prototype.includes method to an ES5 engine, it will even work at runtime. So it is emitted as-is. Note that when you include es2017 in your lib compiler options, you're telling TypeScript that the runtime will support ES2017 typings, and so there is no compile-time warning. Adding typing libraries does not do anything to the runtime itself... so you're responsible for polyfilling/shimming anything you need. From the compiler's perspective it can't deal with the situation where you lied to it about what methods exist at runtime. Obviously that's not much consolation for someone frustrated by a runtime error, though.

Oh well, it is what it is, I guess.


Hope that helps. Good luck!



来源:https://stackoverflow.com/questions/56276280/why-is-es7-array-polyfill-needed-despite-the-tsconfig-target-is-set-to-es5

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!