【问题标题】:What is the advantage of using both TypeScript and Traceur? [closed]同时使用 TypeScript 和 Traceur 有什么好处? [关闭]
【发布时间】:2015-09-05 06:53:10
【问题描述】:

您可以将 TypeScript 配置为输出 ES5 或 ES6。只要您想在原生不支持 ES6 的平台上运行应用程序,您就必须使用 Traceur 之类的编译器(包括 Traceur 运行时库)将 ES6 编译为 ES5。

这样做比简单地告诉 TypeScript 输出 ES5 有什么好处吗? (我不希望应用程序只针对原生 ES6 平台)

据我了解,您不能用 TypeScript (1.5) 编写无法在 ES5 上运行的程序(假设程序可以编译并且您包含正确的库)。我错了吗?

【问题讨论】:

    标签: compilation typescript ecmascript-6 traceur


    【解决方案1】:

    在 TypeScript 上使用 Babel 或 Traceur 的原因

    到目前为止,Typescript 团队选择不使生成的代码依赖于运行时。 ES6 的一些特性可以通过 polyfill 轻松地与 TS 一起使用(例如:ES6 Promises)。其他功能需要转译器和 polyfill 的合作(例如:ES6 生成器)。可以使用带有 TS 的生成器(从 TS 1.6 开始),但目标必须是 ES6。这是使用 Babel 或 Traceur 的一个很好的理由。

    使用 Babel 或 Traceur 而不是 TypeScript 的原因

    但不使用 Babel 和 Traceur 还有其他充分的理由。尝试转译一些 ES6 代码。

    ES6 代码:

    let list = ['ab', 'cd'];
    for (let item of list) {
        console.log(item);
    }
    

    由 TypeScript 产生的 ES5(使用the Playground):

    var list = ['ab', 'cd'];
    for (var _i = 0; _i < list.length; _i++) {
          var item = list[_i];
          console.log(item);
    }
    

    由 Traceur 生产的 ES5(使用the REPL):

    $traceurRuntime.ModuleStore.getAnonymousModule(function() {
        "use strict";
        var list = ['ab', 'cd'];
        var $__4 = true;
        var $__5 = false;
        var $__6 = undefined;
        try {
          for (var $__2 = void 0,
              $__1 = (list)[$traceurRuntime.toProperty(Symbol.iterator)](); !($__4 = ($__2 = $__1.next()).done); $__4 = true) {
            var item = $__2.value;
            {
              console.log(item);
            }
          }
        } catch ($__7) {
          $__5 = true;
          $__6 = $__7;
        } finally {
          try {
            if (!$__4 && $__1.return != null) {
              $__1.return();
            }
          } finally {
            if ($__5) {
              throw $__6;
            }
          }
        }
        return {};
    });
    //# sourceURL=traceured.js
    

    Babel 出品的 ES5(使用the REPL):

    'use strict';
    
    var list = ['ab', 'cd'];
    var _iteratorNormalCompletion = true;
    var _didIteratorError = false;
    var _iteratorError = undefined;
    
    try {
        for (var _iterator = list[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
            var item = _step.value;
    
            console.log(item);
        }
    } catch (err) {
        _didIteratorError = true;
        _iteratorError = err;
    } finally {
        try {
            if (!_iteratorNormalCompletion && _iterator['return']) {
                _iterator['return']();
            }
        } finally {
            if (_didIteratorError) {
                throw _iteratorError;
            }
        }
    }
    

    Traceur 和 Babel 的解决方案很难看,因为变量 list 可能是 an ES6 iterable 并且这些转译器不知道类型。 TypeScript 推断list 的类型是一个数组string[],它只生成数组的代码。

    【讨论】:

    • 所以这似乎是在 TypeScript 中使用 ES5 标志的一个论据。但我的主要问题是,是否有充分的理由使用 ES6 标志,然后使用 Traceur。
    • 好的,那么如果您使用 ES6 Promises 等 ES6 功能,是否可以用 TypeScript 编写一个程序,该程序将无错误地编译到 ES5,但实际上不能在 ES5 上运行?跨度>
    • 部分回答我自己的评论:如果您使用 ES6 Promises,如果您设置了 ES5 标志,TypeScript 编译器将生成错误,但如果您有 ES6 标志则不会。因此编译器会根据目标进行不同的报告。再说一遍:有没有办法编写一个可以用 ES5 编译但不能在 ES5 上运行的程序?
    • @KlasMellbourn 您可以将 ES6 承诺与 ES5 目标一起使用。您只需声明对象Promise,或使用the definition file from DefinitelyTyped。编译器不需要 ES6 目标的定义文件,因为在 ES6 环境中,变量Promise 是一个标准。
    • 在 ES5 浏览器(有或无 TS)上使用 ES6 Promise,需要加载 a polyfill
    猜你喜欢
    • 2011-04-26
    • 1970-01-01
    • 1970-01-01
    • 2011-01-03
    • 2017-10-05
    • 2017-10-16
    • 2015-03-24
    • 2012-09-04
    • 1970-01-01
    相关资源
    最近更新 更多