as const

Freezes literals in an expression: the narrowest types and read-only fields.

On this page

Example

#
TypeScript
const LEVELS = ['easy', 'medium', 'hard'] as const
type Level = (typeof LEVELS)[number]
// type Level = "easy" | "medium" | "hard"

function isLevel(value: string): value is Level {
  return (LEVELS as readonly string[]).includes(value)
}

console.log(LEVELS.length)
console.log(isLevel('hard'), isLevel('expert'))
Result
3
true false

Definition and usage

#

The as const assertion makes TypeScript infer the narrowest possible types: strings become literals ("dark" instead of string), arrays become read-only tuples, and object fields become readonly.

This lets you derive a union of allowed values from a single constant: const LEVELS = ["easy", "hard"] as const and type Level = typeof LEVELS[number] gives "easy" | "hard".

It’s a popular alternative to enums. The values exist in JavaScript as a plain array or object, and the types are generated from them automatically.

Syntax

#
Syntax
const constant = expression as const

More examples

#
An object as an enum replacement
TypeScript
const Status = {
  Draft: 'draft',
  Published: 'published'
} as const

type Status = (typeof Status)[keyof typeof Status]
// type Status = "draft" | "published"

const current: Status = Status.Published
console.log(current)
Result
published

Good practices

#
  • The pattern const X = [...] as const with type T = typeof X[number] gives you both a list of values to loop over and a union type.
  • An object with as const is a lighter alternative to an enum, and it doesn’t generate any extra code.

Related entries

#

Spotted a mistake or missing an example? Write to us.