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
readonlyand 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 6.0.3, not written by hand.
What it does not do
- It does not freeze anything at run time.
Object.freezedoes that;as constis erased and the object is as mutable as it ever was. - It does not go through function calls.
as constapplies 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.

