Skip to content
webtype.orgas const

    ↑↓ move · ⏎ open · esc close

    Operators

    as const

    Stops the compiler widening a literal to its general type.

    What it is

    By default `const x = 1` is `1` but `{ a: 1 }` has `a: number`, because object properties are mutable and a mutable slot cannot promise to stay `1`. `as const` says nothing here will be reassigned, so the literal types can be kept and arrays become readonly tuples. It is the entry point to almost every type-level trick that starts from real data.

    Examples

    • typeof plain
      { kind: string; sides: number; }
    • typeof frozen
      { readonly kind: "circle"; readonly sides: 0; }

      Every property becomes `readonly` and every value keeps its literal type.

    • typeof tuple
      readonly [1, 2]

      An array becomes a readonly tuple, which is how a literal array reaches the type level with its length intact.

    Each resolved type above was printed by TypeScript 5.9.3, not written by hand.

    What it does not do

    • It does not freeze anything at run time. `Object.freeze` does that; `as const` is erased and the object is as mutable as it ever was.
    • It does not go through function calls. `as const` applies to the literal you wrote, not to whatever a function returns.

    Takeaway

    If a type-level trick "does not work on my data", check whether the data widened. `as const` is the answer surprisingly often.