Typescript: const assertions in JSDoc

Created on 16 Mar 2019  路  4Comments  路  Source: microsoft/TypeScript

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.

// @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]).

Use Cases

The same as for const assertions in TS files.

Checklist

My suggestion meets these guidelines:

  • [x] This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • [x] This wouldn't change the runtime behavior of existing JavaScript code
  • [x] This could be implemented without emitting different JS based on the types of the expressions
  • [x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • [x] This feature would agree with the rest of TypeScript's Design Goals.
In Discussion Suggestion

Most helpful comment

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;

All 4 comments

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(),                  // []
};
Was this page helpful?
0 / 5 - 0 ratings

Related issues

remojansen picture remojansen  路  3Comments

Antony-Jones picture Antony-Jones  路  3Comments

blendsdk picture blendsdk  路  3Comments

bgrieder picture bgrieder  路  3Comments

siddjain picture siddjain  路  3Comments