Leo Jiang
Leo Jiang

Reputation: 26075

How can I tell Typescript a method accepts any number of arguments which using a rest argument?

I have a function that's used a lot, so I want to optimize it as much as possible. I benchmarked it and with Babel, the second one is faster by ~10%:

class EventEmitter {
  emit(eventName: string, ...args: any[]) {
    const callbacks = this._callbacks[eventName];
    if (callbacks) {
      for (const cb of callbacks) {
        cb(...args);
      }
    }
  }
}

class EventEmitter {
  emit(eventName: string) {
    const callbacks = this._callbacks[eventName];
    if (callbacks) {
      for (const cb of callbacks) {
        cb(...Array.prototype.slice.call(arguments, 1));
      }
    }
  }
}

In the second case, I still need Typescript to know that emit accepts a variable number of arguments. What's the Typescript syntax for casting emit to (eventName: string, ...args: any[]) => void? If I add ...args: any[] without using it, Babel still adds it to the transpiled version.

Upvotes: 0

Views: 52

Answers (1)

tenshi
tenshi

Reputation: 26326

Add an overload (or external signature):

class EventEmitter {
  emit(eventName: string, ...args: any[]): void;
  emit(eventName: string) {
    const callbacks = this._callbacks[eventName];
    if (callbacks) {
      for (const cb of callbacks) {
        cb(...Array.prototype.slice.call(arguments, 1));
      }
    }
  }
}

More in-depth answer here from an earlier post.

Upvotes: 1

Related Questions