const jsdoc
v3.4 added support for as const to mark a literal expression as immutable and disable type widening. This feature uses the TypeScript type assertion syntax {} as const or <const>{}.
In JS files you can use JSDoc to do type assertions: /** @type {T} */(v)
Unfortunately that doesn't work with const assertions.
// @ts-check
const foo = /** @type {const} */([1]); // Error: cannot find name 'const'
This proposes adding support for /** @type {const} */([1]).
An alternative could be /** @const */([1]).
The same as for const assertions in TS files.
My suggestion meets these guidelines:
It's a small difference, but /** @const */ would be much nicer than /** @type {TypeIOnlyDefinedToMakeThisReadable} */. I see the consistency with /** @type {const} */, too.
When is planning to implement this?
Not sure if it suits typescript's "value as const" pattern but JSDoc already includes the @constant annotation: https://jsdoc.app/tags-constant.html
/** @constant
@type {string}
@default
*/
const RED = 'FF0000';
/** @constant {number} */
var ONE = 1;
As a workaround, you can use identity functions to coerce string and number literals to literal types:
/**
* Identity function. Coerces string/number literals to literal types.
* @template {string | number} T
* @param {T} v
* @return {T}
*/
function c(v) {
return v;
}
/**
* Creates a tuple (array) from the given arguments.
* @template {any[]} T
* @param {T} v
* @return {T}
*/
function t(...v) {
return v;
}
const MyLiteralObject = {
string_before: "foo bar", // string
string_after: c("foo bar"), // "foo bar"
number_before: 42, // number
number_after: c(42), // 42
array_before: [2, "dog"], // (string | number)[]
array_after: t(c(2), c("dog")), // [2, "dog"]
empty_array: [], // any[]
empty_tuple: t(), // []
};
Most helpful comment
Not sure if it suits typescript's "value as const" pattern but JSDoc already includes the
@constantannotation: https://jsdoc.app/tags-constant.html