【问题标题】:Avoid dead code generation for `f(...args: any[])` in TypeScript避免在 TypeScript 中为 `f(...args: any[])` 生成死代码
【发布时间】:2017-05-29 16:38:01
【问题描述】:

我已将一个记录器移植到 TypeScript,与原生 JavaScript 实现相比,我对代码大小感到惊讶。

来源:

class Logger {
  // …    

  trace(...args: any[]) {
    this.invoke(TRACE, arguments);
  }

  debug(...args: any[]) {
    this.invoke(DEBUG, arguments);
  }
}

注意:...args: any[] 只是为了满足编译器的需要。 args 没有使用,也不需要在实现中。

TypeScript 生成:

Logger.prototype.trace = function () {
    var args = [];
    for (var _i = 0; _i < arguments.length; _i++) {
        args[_i - 0] = arguments[_i];
    }
    this.invoke(TRACE, arguments);
};

Babel(或者 Webpack/Uglify 的一些内部,不知道具体)生成:

… }, {
    key: "trace", value: function () {
        for (var e = arguments.length, n = Array(e), t = 0; t < e; t++)n[t] = arguments[t];
        this.invoke(s, arguments)
    }
}, {
    key: "debug", value: function () {
        for (var e = arguments.length, n = Array(e), t = 0; t < e; t++)n[t] = arguments[t];
        this.invoke(l, arguments)
    }
}, …

问题:

  1. 有没有办法告诉 TypeScript 接受方法的任何参数,但不会生成死代码?
  2. 如果不是,是否可以建议编译器忽略那些未使用的参数?

顺便说一句,为什么参数数组的转换效率如此之低?我会使用 Array slice 方法...

【问题讨论】:

    标签: javascript typescript ecmascript-6 babeljs typescript2.3


    【解决方案1】:

    由于您没有使用 ...args: any[] 部分,生成的代码很臃肿...

    你可以使用它:

    trace(...args: any[]) {
        this.invoke(TRACE, ...args);
    }
    

    但是你仍然会得到比你想要的更多的代码,所以你可以在你的方法中添加另一个签名并且没有参数的实际实现:

    trace(...args: any[]);
    trace() {
        this.invoke(TRACE, arguments);
    }
    

    这将确保编译器理解方法需要参数,但实现没有参数,因此不会为它们生成代码。

    【讨论】:

    • TypeScript 非常好(如果有人知道如何使用它的话)——非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-07
    • 2021-02-22
    相关资源
    最近更新 更多