Is there a proper syntax for documenting optional JavaScript parameters, where the optional parameter comes in the middle of the function header (think jQuery, Gulp, etc.)
I've documented the function in the standard way and that works fine. The catch is when I try to set the second parameter to last variable (in the case where the optional parameter wasn't used), my IDE gets confused.
Example:
/**
* @param {number} a_num
* @param {string} [a_str='']
* @param {{}} a_obj
*/
function (a_num, a_str, a_obj) {
if (!a_obj) a_obj = a_str; // doesn't want me to save a string to an object.
a_str = '';
// more stuff
}
If it matters, I'm using PHPStorm by JetBrains, which uses the Google Closure style of docs (mainly). Though I'm looking for a more general, best practice approach.
I suspect I could do something ugly like:
/**
* @param {number} a_num
* @param {string|{}} a_str
* @param {{}} [a_obj=null]
*/
But that doesn't really describe the situation as accurately as I'd like. I'm hoping since this is becoming a common structure that there is something to handle it properly.
Annotating optional parameters in the middle of a function's parameter list are almost as challenging as maintaining code that uses this type of method signature.
Javascript doesn't truly support optional parameters in the middle of a function's argument list (to do that you need named parameters). Instead, functions that advertise this try to discern which version of the function was called based on the number and values of the parameters.
Javascript also doesn't support function overloading.
Recognizing these limitations gives the first clues to supporting what is in essence a documentation strategy. Your annotation must support all types of calls - and by doing this you lose a certain amount of type safety when using a tool that enforces or checks types.
Let's use one of the jQuery.prototype.bind signatures as an example:
jQuery.prototype.bind( eventType [, eventData ], handler )
To document this method, we recognize that two parameters are always required. First let's rearrange and rename the parameters:
jQuery.prototype.bind( eventType, eventDataOrHandler, [ handler ] )
With that rearrangement, the JSDoc becomes clearer:
/**
* @param {string} eventType
* @param {(*|function(Event))} eventDataOrHandler
* @param {function(Event)=} handler
* @return {!jQuery}
*/
jQuery.prototype.bind =
function(eventType, eventDataOrHandler, handler) {};
Unfortunately there is no way to specify that when three arguments are used one set of types is needed, and a different set when two arguments are used.
Perusing the Closure-compiler jQuery externs will give you plenty of examples.