readonly Properties
Mark object properties as immutable after initialization.
readonly Properties is a free TypeScript Academy lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the TypeScript Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
The readonly Modifier
The readonly modifier marks a property that can be set once but never reassigned afterward. It expresses immutability at the type level, helping prevent accidental changes.
interface Point {
readonly x: number;
readonly y: number;
}
const p: Point = { x: 1, y: 2 };
console.log(p.x, p.y);
// p.x = 5; // Error: cannot assign to readonly propertyreadonly on Interfaces
On an interface, readonly documents which fields are fixed after creation. Consumers can read them freely but the compiler blocks any reassignment.
interface Config {
readonly env: string;
retries: number; // mutable
}
const c: Config = { env: 'prod', retries: 3 };
c.retries = 5; // allowed
console.log(c.env, c.retries);Compile Error on Reassignment
Attempting to write to a readonly property is a compile-time error. This catches a whole category of bugs where shared state is mutated unexpectedly.
interface User {
readonly id: number;
name: string;
}
const u: User = { id: 1, name: 'Ada' };
u.name = 'Grace'; // ok
// u.id = 2; // Error
console.log(u);readonly on Class Properties
Classes support readonly too. A readonly field can be initialized at declaration or inside the constructor, but nowhere else.
class Circle {
readonly radius: number;
constructor(r: number) {
this.radius = r; // allowed in constructor
}
}
const c = new Circle(5);
console.log(c.radius);Set Once in the Constructor
The constructor is the one place outside the declaration where you may assign a readonly field. After construction, the value is locked for the object's lifetime.
class Account {
readonly owner: string;
constructor(owner: string) {
this.owner = owner;
}
rename() {
// this.owner = 'x'; // Error: readonly outside constructor
}
}
console.log(new Account('Sam').owner);readonly Parameter Properties
TypeScript's parameter properties let you declare and initialize a readonly field directly in the constructor signature, reducing boilerplate.
class Vector {
constructor(
readonly x: number,
readonly y: number
) {}
}
const v = new Vector(3, 4);
console.log(v.x, v.y);readonly Is Compile-Time Only
Crucially, readonly exists only in the type system. It is erased at runtime — JavaScript has no concept of it. It prevents reassignment in your TypeScript code, not in compiled output reached through untyped paths.
interface Box { readonly value: number; }
const b: Box = { value: 10 };
// At runtime b is a plain object; readonly is not enforced by JS.
console.log(b.value);readonly vs const
Don't confuse them. const stops a variable from being rebound. readonly stops a property from being reassigned. A const object can still have mutable properties unless they're readonly.
const obj = { count: 0 }; // const binding
obj.count = 5; // allowed: property is mutable
console.log(obj.count);Shallow by Nature
readonly is shallow: it protects the property itself, not the contents of an object or array it points to. A readonly reference to an object still allows mutating that object's fields.
interface Holder { readonly data: { n: number }; }
const h: Holder = { data: { n: 1 } };
// h.data = {...}; // Error
h.data.n = 99; // allowed: inner field is not readonly
console.log(h.data.n);Using readonly for Safer APIs
Marking returned objects' fields readonly signals callers shouldn't mutate them. It encodes intent in the type, making misuse a compile error rather than a silent bug.
interface Snapshot { readonly takenAt: number; readonly size: number; }
function snapshot(): Snapshot {
return { takenAt: Date.now(), size: 1024 };
}
const s = snapshot();
console.log(s.size);readonly in Index Signatures
You can even make index signatures readonly, producing a map-like type whose entries can be read but not reassigned through the index.
interface Scores {
readonly [name: string]: number;
}
const scores: Scores = { ada: 95, sam: 88 };
console.log(scores.ada);
// scores.ada = 100; // ErrorQuick Check
Test your understanding of readonly properties.
Recap: readonly Properties
You learned that readonly:
- Allows a property to be set once, then blocks reassignment.
- Can be set at declaration or in the constructor for class fields.
- Is compile-time only and shallow — it doesn't deep-freeze nested data.
- Differs from
const: one guards properties, the other guards variable bindings.
Next, readonly arrays and tuples.
interface Meta { readonly id: number; }
const m: Meta = { id: 42 };
console.log(m.id);Frequently asked questions
Is the “readonly Properties” lesson free?
Yes — the full text of “readonly Properties” is free to read here on the web, and the TypeScript Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the TypeScript Academy course, upgrade to CoddyKit PRO.
What will I learn in “readonly Properties”?
Mark object properties as immutable after initialization. You practise TypeScript Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start TypeScript Academy?
No prior experience is required. TypeScript Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “readonly Properties” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this TypeScript Academy lesson?
Yes. Every TypeScript Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.