When should there be a dot in JSDoc generics?
From a syntax point of view all these types expressions are valid when you run jsdoc index.js
/** @param {Array} x */
const a = x => x;
/** @param {Array.<string>} x */
const b = x => x;
/** @param {Array<string>} x */
const c = x => x;
/** @param {string[]} x */
const d = x => x;
It should be noted that the Google Closure Compiler doesn't seem to recognise the {<type>[]}
type expression e.g. if you compile this:
/** @param {string[]} x */
const a = x => x;
You get the following warning:
JSC_TYPE_PARSE_ERROR: Bad type annotation. expected closing } See https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler for more information. at line 1 character 18
/** @param {string[]} x */
^
JSC_TYPE_PARSE_ERROR: Bad type annotation. expecting a variable name in a @param tag. See https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler for more information. at line 1 character 18
/** @param {string[]} x */
^
See this Google Closure Compiler fiddle.
The static type checker in VS Code will complain about the last three function calls:
// @ts-check
/** @param {Array} x */
const a = x => x;
/** @param {Array.<string>} x */
const b = x => x;
/** @param {Array<string>} x */
const c = x => x;
/** @param {string[]} x */
const d = x => x;
a(['foo', 3]); // OK (we just need an array)
b(['foo', 3]); // ERR: 3 is not a string
c(['foo', 3]); // ERR: 3 is not a string
d(['foo', 3]); // ERR: 3 is not a string
So it pretty much seems like that {Array.<string>}
and {Array<string>}
are the same thing.
Personally I would favour {Array<string>}
over {Array.<string>}
. Why? The dot .
is also a "namespace" separator:
/** @namespace */
const Burrito = {};
/** @constructor */
Burrito.beef = function () {};
/** @param {Burrito.beef} x */
const a = x => x;
a("foo");
a(new Burrito.beef());
The Google Closure compiler will issue a warning about the first call (the second call is fine):
JSC_TYPE_MISMATCH: actual parameter 1 of a does not match formal parameter
found : string
required: (Burrito.beef|null) at line 10 character 2
a("foo");
^
See this Google Closure Compiler fiddle.
If {Array<string>}
and {Array.<string>}
are genuinely the same thing (and I believe that to be true) then I would favour the former over the latter so as to keep the meaning of the .
character unambiguous.