Hint
TypeScript `as const` creates readonly literal types. Without it, object property types are widened to their base type (string, number) and remain mutable. Object.freeze() is the runtime equivalent of `as const`.
// Simulate what TypeScript infers — const narrows to literal, let widens
const direction = 'north'; // inferred: "north" (literal)
let mutableDir = 'north'; // inferred: string (widened)
// Demonstrate by checking type at runtime
console.log(typeof direction); // string at runtime
console.log(direction === 'north'); // true — exact literal value
// const object without assertion — values widened
const config = { host: 'localhost', port: 3000 };
config.host = 'other'; // allowed — string, not literal "localhost"
console.log(config.host);
// Frozen object — runtime immutability
const frozen = Object.freeze({ host: 'localhost', port: 3000 });
try {
frozen.host = 'other'; // silently fails in non-strict, throws in strict
} catch(e) {
// swallow
}
console.log(frozen.host);string true other localhost
Explanation: typeof is always "string" at runtime regardless of literal types. config.host can be reassigned because TypeScript infers it as string (not "localhost" literal). Object.freeze prevents mutation at runtime.
Key Insight: TypeScript as const creates readonly literal types. Without it, object property types are widened to their base type (string, number) and remain mutable. Object.freeze() is the runtime equivalent of as const.