在 TypeScript 中使用最新的 JavaScript 功能,例如 ES2018

Posted

技术标签:

【中文标题】在 TypeScript 中使用最新的 JavaScript 功能,例如 ES2018【英文标题】:Using latest JavaScript features in TypeScript, such as ES2018 【发布时间】:2018-12-05 04:59:07 【问题描述】:

我尝试在 TypeScripts 文档中搜索其配置,但似乎无法找到应该是一个简单问题的答案。

简单地说,如何配置 typescript 编译器以使其知道我们正在使用的 javascript 功能集?

例如,ES2019 登陆,我想“哦,我想给我一些”。在那种情况下,我需要升级什么,以允许编译器转换和填充它需要的东西?

tsconfig 中的 lib 选项让我感到困惑,并且文档对可用库的解释不多。我也无法直接在它们身上找到任何东西。

假设 ES2019 出来了,我为它添加了 lib 选项(假设会有一个)。这是否意味着我现在可以使用 ES2019 功能?如果我希望支持从 ES2019 开始的所有内容,我是否需要为它下面的每个其他版本添加库?或者添加 ES2019 库是否提供了我所需要的一切?

这些库是从哪里来的?它们是核心 TypeScript 库的一部分,所以为了获得更多我必须升级,或者我可以简单地升级一个单独的包,它就可以工作了吗?

最后,这些库是否提供了完全支持该版本规范所需的一切。或者它是功能的子集?

在我们的项目中,我们目前使用 TypeScript 版本 2.5.3

我意识到这是一大堆问题,因此任何有关任何信息或文档链接的任何信息都将不胜感激。

【问题讨论】:

您可能会发现这个答案很有用***.com/questions/50986494/… 【参考方案1】:

这个故事有点复杂,我们应该先把它分成两部分:语言特征和运行时特征。

ES 语言特性

当我们说语言特性时,我们指的是对核心 JavaScript 语言语法的更改。例如ES 2015 增加了对类、箭头函数(=>)和for-of 迭代的支持

Typescript 尝试尽快实现所有稳定的语言功能提案,并将它们向下编译为编译器指定为 target 选项的 ES 版本。所以这意味着如果你有最新的 Typescript 编译器,它增加了对新的 ES 2019 语言功能的支持,你将能够一直向下编译到 ES3。 Typescript 将发出使此类功能在您所针对的任何版本的 ES 中工作所需的代码。

您现在可以看到这一点。如果您以ES5 为目标,箭头函数将编译为常规functions,并使用_this 局部变量来捕获this。类被编译为一个函数和prototype 集合上的适当字段。

ES 运行时特性

除了语言特性之外,我们还有一些运行时特性来描述可用的内置对象类型,以及这些运行时对象具有哪些方法和字段。 ES 的最新版本中的新对象类型示例为 PromiseProxy

Typescript 不为此类功能提供 poly-fill,如果运行时不提供对这些功能的支持,如果您想使用它们,则需要提供自己的 poly-fill 实现。

然而,Typescript 确实需要知道运行时存在哪些内置对象以及它们的方法/字段是什么,这就是 lib 选项的用武之地。它允许您指定运行时环境的外观。

因此,您可以例如以es5 为目标,但指定运行时将具有符合es2015 标准的所有内置对象(一些可能由运行时本身实现,其他可能由您添加通过poly-fills)

两者的交集

上面的划分是一种简化,因为某些语言特性依赖于某些内置对象和方法的存在。

例如,async/await 语言特性依赖于 Promise 的存在。因此,如果您使用async/await 和目标es5,您将收到Promise 构造函数不存在的错误。如果您以es5 为目标,但指定lib: [ 'es2015', 'dom' ],您将不再收到错误,因为您已告诉编译器即使您希望向下编译为es5,在运行时Promise 构造函数将根据es2015 该特定库中表示的运行时规范(不是编译器的问题,这将如何发生,poly-fills 或内置运行时行为)。

一般来说,如果存在这样的依赖,typescript 编译器会发出一个缺少某些类型的错误,您可以升级您的库,或更改您的目标(这将更改使用的默认库),但您必须确保运行时有必要的支持。

例外情况

可能并不总是可以将语言功能一直向下编译到es3(或者因为缺少运行时功能,或者仅仅因为实现该功能的高成本并没有使其成为编译团队)。一个示例是属性访问器 (get/set) 以 es3 为目标时不受支持。但是,如果您使用不受支持的语言功能/目标组合,编译器应该会发出警告。

【讨论】:

这很好地解释了这一切,谢谢。我没有意识到语言特性是 TypeScript 版本的核心。我也没有意识到运行时功能也不是由 TypeScript 自动填充的。我正在运行一个 Angular 应用程序,它为我们提供 pollyfills。我没有意识到这一点。下一个调查是它究竟是什么那被pollyfilled。谢谢! 更多信息github.com/Microsoft/TypeScript/issues/… @YehudaMakarov 不确定这与我的回答有何矛盾。您可以将async/await 语言功能下编译为es3,这不是问题,如果您的运行时不包含它,您仍然需要使用自己的Promise polifill。我在The intersection of the two 部分中所说的一切仍然适用并同样适用于es3,我只是以es5 为例。 @YehudaMakarov 为 async/await 语法生成了一些代码,但生成的代码仍然需要在运行时或 polyfill 中预先存在 Promise 实现。文章明确指出:“请注意,为了让您的代码在 ES3 或 ES5 环境中成功运行,您需要提供 Promise polyfill,因为 Promise 仅在 ES2015 中引入。” @TitianCernicova-Dragomir 非常感谢你,我忽略了这一点。现在很清楚了。 (我看到了你关于这个话题的一些答案。)给你力量:)

以上是关于在 TypeScript 中使用最新的 JavaScript 功能,例如 ES2018的主要内容,如果未能解决你的问题,请参考以下文章

在 TypeScript 中使用最新的 JavaScript 功能,例如 ES2018

我可以一直使用最新版本的Typescript吗?

TypeScript 3.7 最新实用特性解读

我可以使用最新的稳定 TypeScript 还是应该坚持使用 AngularCLI 附带的版本?

在我们的缓存中找不到任何与“最新”匹配的“cra-template-typescript”版本

在“”类型上找不到带有“数字”类型参数的索引签名 - Typescript 编译器错误