Closure annotation for variadic function

888 views Asked by At

I'm writing code to be compiled by the Google Closure Compiler in advanced compilation mode. In some places in my code I have variadic functions which I'd normally write with an empty argument list. I'd access the passed arguments by inspecting the special variable arguments inside the body.

But how can I explain this to the Closure Compiler using annotations? If I don't do any parameter annotation, it complains that the function expects zero arguments. If I write an annotation @param {...*} (to mean an arbitrary number of arguments of arbitrary type), then it complains since the @param annotation must include the name of the parameter. And if I write @param {...*} arguments then it complains that the named argument does not occur in the list of arguments in the function implementation.

The only way I found to make Google happy is by including a dummy name in the argument list as well, even though that is never used. That in turn might confuse readers and perhaps also some linters. So I would prefer some alternative, if one exists.

/** WARNING - Function f1: called with 3 argument(s).
 *            Function requires at least 0 argument(s) and no more than 0 argument(s).
 * @return {number} */
function f1() { return arguments.length; }

/** WARNING - Bad type annotation. expecting a variable name in a @param tag
 * @param {...*}
 * @return {number} */
function f2() { return arguments.length; }

/** WARNING - parameter arguments does not appear in f3's parameter list
 * @param {...*} arguments
 * @return {number} */
function f3() { return arguments.length; }

/** WARNING - Function f4: called with 3 argument(s).
 *            Function requires at least 0 argument(s) and no more than 0 argument(s).
 * @return {number} */
function f4(/* ... */) { return arguments.length; }

/** This works but seems slightly confusing to me.
 * @param {...*} var_args
 * @return {number} */
function f5(var_args) { return arguments.length; }

window["run"] = function() {
  return f1(1,2,3) + f2(1,2,3) + f3(1,2,3) + f4(1,2,3) + f5(1,2,3);
};

Compile this using

java -jar compiler.jar --compilation_level ADVANCED --warning_level VERBOSE foo.js
1

There are 1 answers

0
John On BEST ANSWER

"f5" is the expected pattern.

/** 
 * @param {...*} var_args
 * @return {number} 
 */
function f5(var_args) { return arguments.length; }

An alternative is:

/** @type {function(...*):number} */
function f5() { return arguments.length; }