I am very new to Google Closure Compiler (GCC). I am confused on how to make it show a parameter as optional...
Here is part of my code:
/**
* @param {string} name The event name
* @param {Date} date1 The start date (If alone, the single date) of the event
* @param {Date} date2 The end date of the event
*/
function getEventLink (name,date1,date2) {
// code here
}
I want to have date2
be optional... I found a helpful page on the Closure Compiler, but I didn't see and option for optional... is it possible? If so, how would I do it?
I've tried doing:
/**
* @param {string} name The event name
* @param {Date} date1 The start date (If alone, the single date) of the event
* @param {Date|undefined} date2 The end date of the event
*/
function getEventLink (name,date1,date2) {
// code here
}
Also, with null
instead of undefined
, but neither seemed to work...
The Google Closure Compiler relies on annotations to do its work. Because JavaScript has no syntax for types these have to be written as comments in the source files.
These comments are written using JSDoc and even though GCC has come with its own tags over the years (e.g. @polymer
isn't a "native" JSDoc tag), it does support JSDoc types expressions. (And JSDoc does support the Google Closure Type System in its type expressions too.)
A simple example will clarify:
/**
* @param {string|number} x
*/
const a = x => x;
This is the annotation: @param {string|number} x
. It is information about a thing:
x
This is the type expression: {string|number}
. It is information about the type of a thing.
As you know JavaScript allows to specify default values for parameters in the function signature:
const a = (x=1, y=2, z=3) => x + y + z;
These default values are used if and only if undefined
is passed either implicitly or explicitly:
a();
//=> 6
a(undefined, undefined, 20);
//=> 23
a(null, null, 20);
//=> 20 (null doesn't trigger the default value and is coerced to 0)
There are two annotations possible for an optional parameter. Just pick the one you like:
/** @param {number=} x */
or
/** @param {number} [x] */
However there is only one for an optional parameter with a default value:
/** @param {number} [x=1] */
Even though a(undefined, undefined, 20)
is technically possible in JavaScript, it is however a poor developer experience and GCC may complain.
Optional parameters without declared default values in the function signature should be last otherwise GCC will issue a warning.
In this example z
is the only non-optional parameter however it is the last parameter:
/**
* @param {number} [x=1]
* @param {number} [y=2]
* @param {number} z
*/
const a = (x, y, z) => (x ?? 1) + (y ?? 2) + z;
a(undefined, undefined, 20);
//=> 23
GCC output:
JSC_OPTIONAL_ARG_AT_END: optional arguments must be at the end at line 11 character 10
const a = (x, y, z) => (x ?? 1) + (y ?? 2) + z;
^
This is of course not an issue if all parameters are optional. These examples are all OK:
/**
* @param {number} [x=1]
* @param {number} [y=2]
* @param {number} [z=3]
*/
const a = (x, y, z=3) => (x ?? 1) + (y ?? 2) + z;
or
/**
* @param {number} [x=1]
* @param {number} [y=2]
* @param {number} [z=3]
*/
const a = (x, y, z) => (x ?? 1) + (y ?? 2) + (z ?? 3);
or
/**
* @param {number} [x=1]
* @param {number} [y=2]
* @param {number} [z=3]
*/
const a = (x=1, y=2, z=3) => x + y + z;
Further readings