尽管 tsconfig 目标设置为 ES5,但为什么需要 ES7/array polyfill

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

我在tsconfig.json中有以下设置。我添加了 "es2017" 以使用 Array.includes.:

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

现在,我意识到,我必须将 import 'core-js/es7/array'; 添加到 polyfills.ts,以便在 Internet Explorer 11 中也使用 Array.includestargettsconfig.json设置为es5,没有Array.includes.

为什么我需要添加 polyfill?

TypeScript 没有 auto-polyfill 代码(参见 microsoft/TypeScript#3101). 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.

而且,正如那个问题中提到的,发出运行时代码是 TypeScript 的 non-goal

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


我猜测一些混淆是由于 TypeScript 确实 降低了 some 语言功能在针对早期 EcmaScript 版本时的这一事实。确定功能是否将作为低级代码发出或是否需要 polyfill 时使用的主要标准是 syntax:

如果新语言功能在目标版本中语法无效,那么它要么被降级,要么您将收到编译时警告。您不能填充无效语法。例如,class Foo {} 不是也不可能是有效的 ES5 代码...因此当以 ES5 为目标时它将被转换为构造函数。

另一方面,如果语言功能在目标版本中在句法上有效,它将被发出as-is而不发出警告。所以 [1,2,3].includes(0) 在语法方面是完全有效的 ES5 代码。假设有人在 ES5 引擎中添加一个 Array.prototype.includes 方法,它甚至可以在运行时工作。所以它被发射了as-is。请注意,当您在 lib 编译器选项中包含 es2017 时,您是在告诉 TypeScript 运行时将支持 ES2017 类型,因此没有 compile-time 警告。添加类型库不会对运行时本身做任何事情……所以您需要对 polyfilling/shimming 任何您需要的东西负责。从编译器的角度来看,它无法处理您对运行时存在哪些方法撒谎的情况。显然,对于因运行时错误而沮丧的人来说,这并不是什么安慰。

哦,好吧,我猜就是这样。


希望对您有所帮助。祝你好运!