Many of the jQuery methods return different types based on the number and type of the input parameters. This behavior is akin to function overloading in a traditional language. However, JavaScript doesn't support traditional function overloading and jQuery mimics the behavior by inspecting the function arguments.
For .val
, here's how the method would be annotated if function overloading was supported:
/** @return {number|string|Array.<string>} */
jQuery.prototype.val = function() {};
/**
* @param {number|string|Array.<string>|function(number, *)} newVal
* @return {!jQuery}
*/
jQuery.prototype.val = function(newVal) {};
Since there isn't function overloading, the actual signature for .val
is a combination of both uses:
/**
* @param {(number|string|Array.<string>|function(number, *))=} newVal
* @return {!jQuery|number|string|Array.<string>|function(number, *)}
*/
jQuery.prototype.val = function(newVal) {};
Because of this, if you wish to use the return value of .val
as the input for a separate call to .val
, you must type cast the original return value to specify which usage you expect:
$("#MySelect").val(
/** @type {number|string|Array.<string>} */
($("#MySelect option:first").val()) //note the extra parens
);
This behavior is described in a comment at the top of the jQuery externs file: http://code.google.com/p/closure-compiler/source/browse/trunk/contrib/externs/jquery-1.7.js#20