const and mutable objects
A sealed const jar holds one value, and TypeScript labels it exactly. With a number everything is clear: const limit = 5 stays five forever. But what if the constant holds an object?
const cart = { total: 0 };
const scores = [3, 5];
cart.total = 1500;
scores.push(4);
console.log(cart.total, scores.length); // 1500 3The program compiles without errors and prints 1500 3. Let's go through it line by line:
const cart = { total: 0 };—the constantcartholds an object with the propertytotal.const scores = [3, 5];—the constantscoresholds an array of two numbers.cart.total = 1500;changes a property inside the object, andtscdoes not object.scores.push(4);adds an element to the same array—again with no error.console.logprints1500 3:totalnow holds1500, and the array has three elements.
The object and the array changed, although both are declared with const. So what does const forbid?
What const forbids
const forbids giving the name a new value—writing another object into cart, even one of exactly the same shape:
const cart = { total: 0 };
cart = { total: 1500 }; // ✗error TS2588: Cannot assign to 'cart' because it is a constant.The message means: "you cannot give cart a new value because it is a constant". In JavaScript this line would fail only at run time, with the error TypeError: Assignment to constant variable. TypeScript finds it earlier—at compile time.
What can change inside
A constant holds the same value all the time—the same object or array. What lies inside it, const does not guard:
- an object's properties:
cart.total = 1500; - an array's elements:
scores[0] = 10; - methods that change an array:
scores.push(4).
This is where the sealed-jar analogy ends: it holds for numbers and strings, which have no parts. An object is more like a chest of drawers. const glues the label cart firmly to one chest, but its drawers still slide out.
Interviewers often ask: "Can you change an object declared with const?" The answer: its properties, yes; writing another object into the name, no.
Property types stay general
You have already seen that const point = { x: 5 } gets the type { x: number; }. The same goes for cart: its type is { total: number; }. So the property takes any other number, but not a value of another type:
const cart = { total: 0 };
cart.total = "бесплатно"; // ✗error TS2322: Type 'string' is not assignable to type 'number'.const does not guard the object's contents, but the type does: total can change, but only to a number.
Common mistake
Declaring with const a value that later changes as a whole, such as a counter:
const attempts = 0;
attempts = attempts + 1; // ✗error TS2588: Cannot assign to 'attempts' because it is a constant.attempts + 1 is a new number, and it can be written into the name only if the name is declared with let. The fix is let attempts = 0;. The rule for choosing is the same as in JavaScript: const by default, let when the name will get a new value.
Key points
constforbids giving the name a new value:cart = …is errorTS2588.- The contents of an object or array in a
constcan change: properties, elements,push. - Property types are inferred as general:
cart.totalof typenumbertakes another number, but not a string. - A value that changes as a whole, such as a counter, needs
let.