google / closure-compiler

A JavaScript checker and optimizer.
https://developers.google.com/closure/compiler/
Apache License 2.0
7.4k stars 1.15k forks source link

FR: template-matching on "rest" params of generic functions #2221

Open shicks opened 7 years ago

shicks commented 7 years ago

I sometimes write functions that take arbitrary functions as arguments and return functions that expect the same (or slightly modified) types of parameters. Currently there's no way to do this without loosening the type information on the returned function. Some sort of template syntax (say, *REST, cribbing from python) could allow more precise matching:

/**
 * @param {function(*REST)} func
 * @return {function(number, *REST)}
 * @template REST
 */
function delayed(func) {
  return function(time, ...args) {
    setTimeout(func.bind(this, ...args), time);
  };
}

Another use cases is mixins (where the @param and @return would be of the form function(new: T, *REST), again with the possibility of adding an extra parameter).

dimvar commented 7 years ago

John has proposed ICallable<T> for handling types that describe functions with properties, which we will add at some point. Then, you can rewrite this slightly modified, by currying the return function. I doubt that we'll implement this with the proposed syntax, b/c it's probably too specialized to justify the cost of supporting it.

/**
 * @param {!ICallable<T>} func
 * @return {function(number):!ICallable<T>}
 * @template T
 */
function delayed(func) {
  return function(time) {
    return function(...args) {
      setTimeout(func.bind(this, ...args), time);
    }
  };
}