以 ES5 / ES3 为目标时,Typescript 会转译什么?
What will Typescript transpile when targeting ES5 / ES3?
我试图了解 Typescript 编译器何时会转换代码以使其与我指定的目标 ECMAScript 版本(ES5 或 ES3)兼容。
例如,TSC 可以很好地转译 for(var int of intArray)
,但不会转译 Number.isInteger()
(根据 w3schools,这是 ES6 的一个特性)。
IE < 11.0 不支持 Number.isInteger()
,所以这是一个问题。 Visual Studio(和 VS Code)不提供不兼容警告,也不会被转译。
什么可以转译,什么不能转译?我最初期望一切都会被转译,这样我就不必跟踪这样的事情,但事实似乎并非如此。
编译器支持基于您告诉它使用的库的功能。
有两种方法可以控制编译器将使用哪个库,使用 target
和 lib
compiler options.
上面写的link:
If --lib is not specified a default library is injected. The default
library injected is:
► For --target ES5: DOM,ES5,ScriptHost
► For
--target ES6: DOM,ES6,DOM.Iterable,ScriptHost
所有不同的库都是 part of the project。
如果您的目标是 es3
或 es5
,那么您不能使用 Number.isInteger()
,因为它(如您所述)是一个 es6
功能。
如果你有一个 polyfil,那么你仍然可以使用 es6
lib:
来定位 es5
--target es5 --lib DOM,ES6,ScriptHost
或者您可以只复制 lib.es6.d.ts 的定义:
interface NumberConstructor {
isInteger(number: number): boolean;
}
你可以使用 let
、const
、for/of
之类的东西而不考虑目标的原因是编译器知道如何生成等效代码,即使该功能不是'所选目标不支持。
例如:
const arr = [1, 2, 3];
for (let num of arr) {}
编译为:
var arr = [1, 2, 3];
for (var _i = 0, arr_1 = arr; _i < arr_1.length; _i++) {
var num = arr_1[_i];
}
如果没有指定目标。
可以看到,const
和let
变成了var
,for/in
变成了常规的for
。
Number.isInteger()
有所不同,它是某些目标中不存在的功能,例如 Promise
和 'Symbol`。
编译器不会添加 polyfill,由您自行添加,然后告诉编译器它就在那里。
TypeScript transpiles 但不 polyfill。因此,一种思考方式是 target
中的任何无效语法都将 转译 为有效语法。例如,当使用 class
关键字并将目标设置为 ES5
时,它将转译为:
class Greeter {
}
对此:
var Greeter = /** @class */ (function () {
function Greeter() {
}
return Greeter;
}());
(你可以用这个 here 玩得更多。)
另一方面,它不会添加缺少的功能,您必须自己 polyfill。 Number.isInteger()
是有效的 ES5
语法,它只是 ES5
中不存在的功能。你可以通过导入 babel-polyfill
(which uses core-js
under the hood) or using a service like polyfill.io.
来自己填充这个
注意:不要将 lib
选项与 polyfill 混淆。此不 polyfill 功能。它只是告诉 TypeScript 就好像这些 ES 版本的特性存在一样,所以它会适当地对它们进行类型检查。对于您支持的浏览器,您仍然需要自己处理 polyfill 部分。如果你没有指定合适的 lib
s,TypeScript 会抱怨它不知道 Number.isInteger()
代表什么。
我不知道 TypeScript 转换功能的完整列表,但您可以看到 table TypeScript+core-js
polyfills here。
更多关于 polyfill 与转译的阅读 here.
我试图了解 Typescript 编译器何时会转换代码以使其与我指定的目标 ECMAScript 版本(ES5 或 ES3)兼容。
例如,TSC 可以很好地转译 for(var int of intArray)
,但不会转译 Number.isInteger()
(根据 w3schools,这是 ES6 的一个特性)。
Number.isInteger()
,所以这是一个问题。 Visual Studio(和 VS Code)不提供不兼容警告,也不会被转译。
什么可以转译,什么不能转译?我最初期望一切都会被转译,这样我就不必跟踪这样的事情,但事实似乎并非如此。
编译器支持基于您告诉它使用的库的功能。
有两种方法可以控制编译器将使用哪个库,使用 target
和 lib
compiler options.
上面写的link:
If --lib is not specified a default library is injected. The default library injected is:
► For --target ES5: DOM,ES5,ScriptHost
► For --target ES6: DOM,ES6,DOM.Iterable,ScriptHost
所有不同的库都是 part of the project。
如果您的目标是 es3
或 es5
,那么您不能使用 Number.isInteger()
,因为它(如您所述)是一个 es6
功能。
如果你有一个 polyfil,那么你仍然可以使用 es6
lib:
es5
--target es5 --lib DOM,ES6,ScriptHost
或者您可以只复制 lib.es6.d.ts 的定义:
interface NumberConstructor {
isInteger(number: number): boolean;
}
你可以使用 let
、const
、for/of
之类的东西而不考虑目标的原因是编译器知道如何生成等效代码,即使该功能不是'所选目标不支持。
例如:
const arr = [1, 2, 3];
for (let num of arr) {}
编译为:
var arr = [1, 2, 3];
for (var _i = 0, arr_1 = arr; _i < arr_1.length; _i++) {
var num = arr_1[_i];
}
如果没有指定目标。
可以看到,const
和let
变成了var
,for/in
变成了常规的for
。
Number.isInteger()
有所不同,它是某些目标中不存在的功能,例如 Promise
和 'Symbol`。
编译器不会添加 polyfill,由您自行添加,然后告诉编译器它就在那里。
TypeScript transpiles 但不 polyfill。因此,一种思考方式是 target
中的任何无效语法都将 转译 为有效语法。例如,当使用 class
关键字并将目标设置为 ES5
时,它将转译为:
class Greeter {
}
对此:
var Greeter = /** @class */ (function () {
function Greeter() {
}
return Greeter;
}());
(你可以用这个 here 玩得更多。)
另一方面,它不会添加缺少的功能,您必须自己 polyfill。 Number.isInteger()
是有效的 ES5
语法,它只是 ES5
中不存在的功能。你可以通过导入 babel-polyfill
(which uses core-js
under the hood) or using a service like polyfill.io.
注意:不要将 lib
选项与 polyfill 混淆。此不 polyfill 功能。它只是告诉 TypeScript 就好像这些 ES 版本的特性存在一样,所以它会适当地对它们进行类型检查。对于您支持的浏览器,您仍然需要自己处理 polyfill 部分。如果你没有指定合适的 lib
s,TypeScript 会抱怨它不知道 Number.isInteger()
代表什么。
我不知道 TypeScript 转换功能的完整列表,但您可以看到 table TypeScript+core-js
polyfills here。
更多关于 polyfill 与转译的阅读 here.