A cast to const, /** @type {const} */ (value), is the JavaScript spelling of TypeScript's as const. TypeScript then keeps every literal as its own type ("/cart", not string), makes every property readonly, and turns array literals into read-only tuples. TypeScript 4.5 added the JSDoc form.
It is the usual way to define a fixed set of values once and derive a type from it: (typeof ROUTES)[keyof typeof ROUTES] is the union of the route paths, and a path that is not in the object is TS2345.
At a glance
| Use | JSDoc in a .js file | TypeScript in a .ts file |
|---|---|---|
| An object | const ROUTES = /** @type {const} */ ({ home: "/", cart: "/cart" }); | const ROUTES = { home: "/", cart: "/cart" } as const; |
| An array | const SIZES = /** @type {const} */ (["S", "M", "L"]); | const SIZES = ["S", "M", "L"] as const; |
Examples
export const ROUTES = /** @type {const} */ ({
home: "/",
cart: "/cart",
account: "/account",
});
/** @typedef {(typeof ROUTES)[keyof typeof ROUTES]} Path */
/** @param {Path} path */
export function go(path) {
location.assign(path);
}
go(ROUTES.cart);
go("/checkout");error TS2345: Argument of type '"/checkout"' is not assignable to parameter of type 'Path'.export const ROUTES = {
home: "/",
cart: "/cart",
account: "/account",
} as const;
type Path = (typeof ROUTES)[keyof typeof ROUTES];
export function go(path: Path) {
location.assign(path);
}
go(ROUTES.cart);
go("/checkout");error TS2345: Argument of type '"/checkout"' is not assignable to parameter of type 'Path'.jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} const ROUTES = /** @type {const} */ ({ home: "/", cart: "/cart" });
ROUTES.cart = "/basket";error TS2540: Cannot assign to 'cart' because it is a read-only property.
export { ROUTES };jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} const origin = /** @type {const} */ ([0, 0]);
/** @param {readonly [number, number]} point */
export function distanceFromOrigin([x, y]) {
return Math.hypot(x, y);
}
distanceFromOrigin(origin);
const loose = [0, 0];
distanceFromOrigin(loose);error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'readonly [number, number]'.
Target requires 2 element(s) but source may have fewer.jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} const ROUTES = { home: "/", cart: "/cart" } as const;error TS8016: Type assertion expressions can only be used in TypeScript files.
export { ROUTES };jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} What changes
Without the assertion, { home: "/" } is typed { home: string }, because object properties are mutable. With it, the type is { readonly home: "/" }: assigning to ROUTES.cart is TS2540, and the literal can be used where a union of literals is expected.
An array becomes a read-only tuple: [0, 0] is readonly [0, 0], which fits a readonly [number, number] parameter where a plain number[] does not (TS2345 in the third example).
Not a freeze
A const assertion changes types only. The object can still be modified at run time by code that ignores the types; wrap it in Object.freeze as well if that matters.
Gotchas
- The parentheses are required, as with every JSDoc cast.
as constitself is TypeScript syntax: in a.jsfile it is TS8016.- Not to be confused with the
@consttag, which TypeScript ignores.
Questions
How do I write as const in JavaScript?
/** @type {const} */ (value), with the parentheses. It works since TypeScript 4.5.
Sources
- TypeScript 4.5: const assertions and default type arguments in JSDoc · TypeScript release notes
- TypeScript 3.4: const assertions · TypeScript release notes
- JSDoc Reference: casts to const · TypeScript handbook
Last reviewed 20 October 2026.