2017-02-07 48 views
12

我发现我很困惑的目标和lib选项以及它们如何与源代码支持的功能进行交互。我觉得这些文档需要改进一点,所以在提出问题之前在这里提问。需要澄清的目标和lib编译器选项

我天真地认为目标指定了输出代码运行所需的JS版本(通过添加模块加载器)。因此,我们可以始终使用TS在源代码中支持的所有高级JS功能(如对象扩展),并且编译器会为我们指定的目标生成合适的代码。我认为它手边有polyfills等,代码将运行在目标虚拟机上。

但是,lib选项的文档指定默认库取决于目标。但是,库会影响可用的源类型,从而影响我们可以使用的代码。因此,我们可以使用的源特征取决于目标。这不像我预料的那样。我应该说我对lib的理解是,他们用不同的API来打样,尽管文档并没有真正地说出它们的内容。

我可以看到,这里有一些不依赖于类型和其他类型的语言功能。但目前还不清楚这是否是这种情况的原因之一。

有人可以澄清这一点吗?

第二个问题是为什么当ES6和ES2015通常被记录为同一事物时,它们都存在。

感谢

回答

26

(这开始作为一个评论,但它得到了太久。)

这是一个有点混乱部分,因为有一些背后的历史。我没有资格权威回答这个问题,但由于早期的发展中,我一直在关注打字稿,这是我的理解:

  • --target告诉编译器包括哪些库版本在编译时(例如ES5会给出一个编译器错误如果使用Promise,但ES6会知道所有关于Promise什么版本的JS是编译器发出(例如ES5将向下编译类语法,但ES6会离开它)。
  • --lib稍后添加,可以更好地控制在编译时使用的库版本,而无需更改发布的JS目标。例如,常见问题是您可能包含ES6库功能的填充,例如Promise,但您希望通过向下编译class语法来定位ES5浏览器。之前--lib是你要么不得不目标ES6以避免编译错误约Promise,然后用巴贝尔再次下调编译,或者您可以指定ES5并为Promise提供自己的类型定义,这样编译器不会给你错误。现在用--lib就可以简单地说你的--target ES5--lib ES6,编译器不会抱怨Promise,但仍然可以下载到ES5。
  • 这两个选项都不会导致TS发出任何库polyfills(Promise等),正如您明显发现的那样;您有责任提供正确的运行时库。它只发出一些低级语言兼容性帮助程序,如__extends__awaiter(不同之处在于classasync不仅仅是一个可以在运行时填充的API,它是一种具有语法含义的语言功能)。 --lib选项只是根据您在运行时知道的信息获取正确级别的编译检查的方法。
  • 至于为什么同时存在ES6ES2015,这只是因为ECMAScript更改了名称,TS留下了旧名称作为向后兼容的有效选项。 :)

你会发现很多的这个涵盖在这些TS问题:

+0

感谢一个很好的答案。所以我发现混淆的根源在于''-target'''做了这两件事,另外一些语言特性是向下编译的,而另一些则不是,但确实需要在源代码中使用lib。 –

+0

这也是回答另一个问题 - 为什么地球上你会使用TS和Babel :)因此,一个很好的方式来定位目前许多当前的浏览器,目标是ES中的ES6,并将Babel转换为ES5。 –