Things I found myself researching over and over without taking the time to write them down. Until now.
Table of Contents
- Should I use
{String}vs{string}or{Number}vs{number}...? - Type Expression: Optional vs Nullable vs Non-nullable
- When do I need to use the
@functiontag?
These aren't interchangeable type expressions. For example if a symbol is meant to hold a literal string you should use {string} and not {String}: (The same is true for {Number} e.g. new Number(42) vs {number} e.g. 42 and {Boolean} e.g. new Boolean and {boolean} e.g. false.)
/** @param {String} x */
const a = x => x;
/** @param {string} x */
const b = x => x;| fn | Annotation | fn("foo") | fn(new String("foo")) |
|---|---|---|---|
| a | {String} x |
╳ | ✓ |
| b | {string} x |
✓ | ╳ |
╳ represents the JSC_TYPE_MISMATCH error in GCC.
Examples have been compiled with the Google Closure Compiler and are available here.
Objects and arrays are covered respectively by the {Object} and {Array} type expressions which both handle literal and constructor expressions: ({} vs new Object and [] vs new Array)
/** @param {Object} x */
const a = x => x;
/** @param {Array} x */
const b = x => x;| fn | Annotation | fn() | fn(<literal>) | fn(<constructor>) | fn(null) | fn(undefined) |
|---|---|---|---|---|---|---|
| a | {Object} x |
╳1 | ✓ | ✓ | ✓ | ╳2 |
| b | {Array} x |
╳1 | ✓ | ✓ | ✓ | ╳2 |
╳1 represents the JSC_WRONG_ARGUMENT_COUNT error in GCC.
╳2 represents the JSC_TYPE_MISMATCH error in GCC.
Examples have been compiled using the Google Closure Compiler and are available here.
Note that arrays, objects (and functions) are nullable by default. So {Object} is the same as {?Object} which explains why a(null) passed the type check.
Note that the following are already nullable, and thus prepending
?is redundant, but is recommended so that the intent is clear and explicit:?Object,?Array,?Function
See Types in the Closure Type System
There are two type expressions: {function()} and {Function}. The former being preferred over the latter as it allows to document parameters and return values.
/** @param {Function} x */
const a = x => x;
/** @param {function()} x */
const b = x => x;| Code | {Function} x |
{function()} x |
|---|---|---|
fn(() => 42); |
✓ | ✓ |
fn(function () { return 42 }); |
✓ | ✓ |
fn(new Function('return 42')); |
✓ | ✓ |
fn(); |
╳1 | ╳1 |
fn(null); |
✓ | ╳2 |
fn(undefined); |
╳2 | ╳2 |
╳1 represents the JSC_WRONG_ARGUMENT_COUNT error in GCC.
╳2 represents the JSC_TYPE_MISMATCH error in GCC.
Examples have been compiled using the Google Closure Compiler and are available here.
Note that {Function} is the same as {?Function} meaning that it is nullable by default.
A type expression is used to document the type of many different things such as a parameter, a variable or a property or the return value of a function. JSDoc supports the Google Closure Compiler Type System in type expressions.
/** @param {number} x */
const a = x => x;
/** @param {number=} x */
const b = x => x;
/** @param {number} [x] */
const c = x => x;
/** @param {number} [x=42] */
const d = x => x;
/** @param {!number} x */
const e = x => x;
/** @param {!number=} x */
const f = x => x;
/** @param {!number} [x] */
const g = x => x;
/** @param {!number} [x=42] */
const h = x => x;
/** @param {?number} x */
const i = x => x;
/** @param {?number=} x */
const j = x => x;
/** @param {?number} [x] */
const k = x => x;
/** @param {?number} [x=42] */
const l = x => x;| fn | Annotation | Expect | Default | fn() | fn("42") | fn(null) | fn(undefined) | fn(42) |
|---|---|---|---|---|---|---|---|---|
| a | {number} x |
Number | ╳1 | ╳2 | ╳2 | ╳2 | ✓ | |
| b | {number=} x |
Number or undefined |
undefined |
✓ | ╳2 | ╳2 | ✓ | ✓ |
| c | {number} [x] |
Number or undefined |
undefined |
✓ | ╳2 | ╳2 | ✓ | ✓ |
| d | {number} [x=42] |
Number or undefined |
42 |
✓ | ╳2 | ╳2 | ✓ | ✓ |
| e | {!number} x |
Number | ╳1 | ╳2 | ╳2 | ╳2 | ✓ | |
| f | {!number=} x |
Number or undefined |
undefined |
✓ | ╳2 | ╳2 | ✓ | ✓ |
| g | {!number} [x] |
Number or undefined |
undefined |
✓ | ╳2 | ╳2 | ✓ | ✓ |
| h | {!number} [x=42] |
Number or undefined |
42 |
✓ | ╳2 | ╳2 | ✓ | ✓ |
| i | {?number} x |
Number or null |
╳1 | ╳2 | ✓ | ╳2 | ✓ | |
| j | {?number=} x |
Number, null or undefined |
undefined |
✓ | ╳2 | ✓ | ✓ | ✓ |
| k | {?number} [x] |
Number, null or undefined |
undefined |
✓ | ╳2 | ✓ | ✓ | ✓ |
| l | {?number} [x=42] |
Number, null or undefined |
42 |
✓ | ╳2 | ✓ | ✓ | ✓ |
╳1 represents the JSC_WRONG_ARGUMENT_COUNT error in GCC.
╳2 represents the JSC_TYPE_MISMATCH error in GCC.
Examples have been compiled with the Google Closure Compiler and are available here.
This would be necessary when a function gets assigned to a variable for example.
This marks an object as being a function, even though it may not appear to be one to the parser. It sets the doclet's @kind to 'function'.
See JSDoc @function tag documentation.
If we dump the doclets of index.js with: jsdoc -X index.js
// index.js
/** @param {?} y */
function a(y) {}
/** @param {?} y */
const b = a;
/**
* @function
* @param {?} y
*/
const c = a;Doclet for a:
{
// ...
"name": "a",
"longname": "a",
"kind": "function",
"scope": "global"
}Doclet for b:
{
// ...
"name": "b",
"longname": "b",
"kind": "constant",
"scope": "global"
}Doclet for c:
{
// ...
"name": "b",
"longname": "b",
"kind": "function",
"scope": "global"
}We can see that b doesn't appear as a function to the JSDoc parser. This isn't the case for c as we explicitly marked it as such with the @function tag.