-
Notifications
You must be signed in to change notification settings - Fork 12.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
const assertions in JSDoc #30445
Comments
It's a small difference, but |
When is planning to implement this? |
Not sure if it suits typescript's "value as const" pattern but JSDoc already includes the /** @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(), // []
}; |
@pastelmind's idea one solution, but I'm concerned about the overhead.
I think ajafff's idea is a good one. I'm sorry I didn't have an idea, // @ts-check
// ---- Substitute cases
const foo = /** @type {[1]} */ ([1]); // Good: foo is type [1]
foo[0] = 2; // <- ERROR: Type checking is working well!!
// ---- Cases that alternative solutions cannot handle
const complex1 = {
/** @type {1} */
item: 1, // <- Type check ERROR: 1 is a number
};
/** @constant */
const complex2 = {
/** @constant {1} */
item: 2, // <- Type check ERROR: 1 is a number
};
complex2.item = 3; // Type checking is not working. |
I want to provide an additional use case, now that #41631 was reopened and the official workaround is to use 💻 Use CasesIn The type declarations already reflect this: While these tests are hard-coded for string literals, in the real world most of our developers use JS and IDs are often built on the fly, e.g. const id = `my-tree.0.${someString}`; // inferred as string
setObject(id, { /* I could really use a better type for this object */ }); If |
It's more one use case: https://github.com/ThomasAribart/json-schema-to-ts. It doesn't work with JSDoc types without |
I'm also looking for solution to enable auto-completion and code hint for our design system's theme object which is ideally limited to vanilla JS and JSDoc. Essentially, when developer type a theme's key, they should see the actual value of that key so that they don't go back and forth looking up the theme's spec. This feature is the key to it. Currently, I'm doing a work-around with tuple (for array) and literal string type for object key like so: /**
* Tuple with literal type
* @type {[
'12px',
'16px',
'20px',
'24px',
]}
*/
const sizesScale = [
'12px', // 0
'16px', // 1
'20px', // 2
'24px', // 3
];
// The literal types will follow sub-sequence assignment like so:
const sizes = {
...sizesScale,
xs: sizesScale[0],
sm: sizesScale[1],
md: sizesScale[2],
lg: sizesScale[3],
}
/**
* Literal types in enum-like objects
* @type {{
body: 400,
heading: 700,
normal: 400,
bold: 700,
}}
*/
const fontWeights = {
body: 400,
heading: 700,
normal: 400,
bold: 700,
}; As you can see, we can't avoid the values duplication, but since the This feature will eliminate the duplication. |
Any update on this? |
Fwiw, this is one of the main missing features of JavaScript+JSDoc that is pushing me to migrate to TypeScript. I've run into it several times in the past couple years. Most other problems have at least adequate solutions with JSDoc, but this doesn't. |
For anyone coming here and scrolling to the bottom to see if it's fixed, it's fixed! You can use // type is number[]
const arr1 = [1, 2, 3]
// type is readonly [1, 2, 3]
const arr2 = /** @type {const} */ ([1, 2, 3]) Note that the type coercion has to be written inline and the parenthesis are necessary. Hope this helps :) |
this does not seem to be working anymore ? |
actually it seems to work in js files, not sure if it is supposed to work on the playground |
It does work on the playground if you change the language from TypeScript to JavaScript under the |
Not work for json file require - const is ignored. let translations = /** @type { const } */ (require('./translations.js')); |
Search Terms
const jsdoc
Suggestion
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.
This proposes adding support for
/** @type {const} */([1])
.An alternative could be
/** @const */([1])
.Use Cases
The same as for const assertions in TS files.
Checklist
My suggestion meets these guidelines:
The text was updated successfully, but these errors were encountered: