Avoid dead code generation for `f(...args: any[])` in TypeScript

145 views Asked by At

I've ported a logger to TypeScript and was negatively surprised about code size compared to native JavaScript implementation.

Source:

class Logger {
  // …    

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

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

Note: the ...args: any[] is only there to satisfy the compiler. args is not used and not needed in the implementation.

TypeScript generates:

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

Babel (or some internals of Webpack/Uglify, don't know exactly) generate:

… }, {
    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)
    }
}, …

Questions:

  1. Is there a way to tell TypeScript to accept any parameters for the methods, but in a way so no dead code will be generated?
  2. If not, can the compiler be advised to ignore those unused arguments?

BTW why is the arguments array converted so inefficiently? I'd use Array slice method...

1

There are 1 answers

1
Nitzan Tomer On BEST ANSWER

The generated code is bloated because of the ...args: any[] part which you are not using...

You can use it:

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

But you'll still get more code than you want, so you can add another signature to your methods and have the actual implementation with no args:

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

This will ensure that the compiler understands that the methods expect arguments but the implementation doesn't have them so it won't generate code for them.