TypeScript Tutorial
TypeScript Const and Readonly
const means this binding will not be reassigned. readonly and as const go further on objects and arrays.
A name that must stay put
Write const when that binding should not be assigned again. The compiler treats a latermaxScore = 50 as an error. You get the mistake at compile time, not as a wrong answer after the program runs.
Use it for values that are facts in this program: a maximum score, a tax rate, a label you print in several places. If you need to rebind the name, use let. C++ const also locks a name; TypeScript splits the idea: const for the binding, readonly for fields inside an object.
const variables
Initialize a const on the same line you declare it. There is no later chance to fill it in. After that, you may read it as often as you like.
Example
const maxScore: number = 100;
const score: number = 88;
console.log(score + " / " + maxScore);maxScore = 50; after the declaration does not compile. That is the feature. If the number must change, use let.
const does not freeze an object
const player means you will not write player = somethingElse. The object’s fields can still change. push on a const array is legal for the same reason: the binding is fixed, the contents are not.
Example
const nums: number[] = [8, 3];
nums.push(5);
console.log(nums.join(" "));
console.log(nums.length);Output is 8 3 5 then 3. nums = [] would not compile. To lock the contents too, you need readonly or as const.
Open /typescript/try and try nums = [1]; after the push. tsc rejects the reassignment.
readonly fields
On a type or a class, readonly means that property is not assigned after the object is created. Construction (or an object literal that matches the type) may set it. Later writes fail at compile time.
Example
type Point = {
readonly x: number;
readonly y: number;
};
const origin: Point = { x: 0, y: 0 };
console.log(origin.x + "," + origin.y);
class Box {
readonly id: number;
constructor(id: number) {
this.id = id;
}
}
const box = new Box(7);
console.log(box.id);Output is 0,0 then 7. origin.x = 1 does not compile.box.id = 8 does not compile. A getter that only returns a field is often enough; readonly is for when there is no setter on purpose.
as const narrows literals
as const tells the checker the array or object is a fixed tuple or a fixed set of literal types. Elements become readonly. String fields become the specific string, not string. Use it for lookup tables you will never mutate.
Example
const days = ["Mon", "Tue", "Wed"] as const;
console.log(days[1]);
console.log(days.length);
const status = { ok: 200, notFound: 404 } as const;
console.log(status.ok);Output is Tue, then 3, then 200. days.push("Thu") does not compile: the tuple is readonly. status.ok has type 200, not a generalnumber.
What each keyword locks
| Write | Meaning |
|---|---|
const n = 3 | This binding will not be reassigned. |
readonly x: number | This property will not be written after creation. |
as const | Literals stay literal; arrays become readonly tuples. |
let n = 3 | Reassignment allowed; still typed. |
Mark what you only read
Start with const for names you never rebind. Add readonly on fields that must not change. Use as const for small fixed tables. Next: namespaces, which keep those names from colliding with someone else’s n or status.