Constants in TypeScript
Modeling immutability with const, as const, and readonly utilities.
const variables
const prevents rebinding but not deep immutability.
const config = { base: "/api", retries: 3 };
config.retries = 5; // allowed (object is still mutable)
as const (const assertions)
Freezes literal types and marks properties/array elements as readonly.
const ROUTES = {
home: "/",
about: "/about",
status: 200,
} as const;
// type: { readonly home: "/"; readonly about: "/about"; readonly status: 200 }
Works on arrays/tuples too:
const DIRECTIONS = ["up", "down"] as const; // readonly ["up", "down"]
Readonly<T> and readonly arrays
type ReadonlyUser = Readonly<{ id: number; name: string }>;
const users: ReadonlyArray<string> = ["a", "b"]; // no mutating methods
satisfies operator
Keep precise literals while ensuring a wider shape.
const settings = {
mode: "prod",
retries: 3,
} as const satisfies { mode: "prod" | "dev"; retries: number };
Object.freeze and typing
Object.freeze returns Readonly<T> at runtime but does not deeply freeze nested objects.
const frozen = Object.freeze({ a: { b: 1 } }); // a: Readonly<{ b: number }>
For deep immutability, model types with mapped types or use utility libraries.
Const enums (caveat)
const enum inlines values at compile time but can break interop/tooling. Prefer enum or union literals unless you control emit (preserveConstEnums: true).
Summary
conststops rebinding; useas constto preserve literals- Use
readonlyutilities for shallow immutability; model deep immutability via types