In TypeScript, the readonly keyword is used to make a
property read-only after it has been initialized. A readonly property
can be accessed, but it cannot normally be reassigned after the object
has been created.
readonly when a property should not be changed after
its initial value is assigned.
A readonly property is a property whose value cannot be reassigned after initialization.
interface Student {
readonly id: number;
name: string;
}
Here, id is readonly, while name
can be changed.
The basic syntax is:
readonly propertyName: type;
Example:
interface User {
readonly id: number;
}
A readonly property can be assigned when the object is created.
interface Student {
readonly id: number;
name: string;
}
const student: Student = {
id: 101,
name: "Amit"
};
Readonly properties can be accessed like normal properties.
interface Student {
readonly id: number;
name: string;
}
const student: Student = {
id: 101,
name: "Amit"
};
console.log(student.id);
Reading a readonly property is allowed.
A readonly property cannot normally be reassigned after initialization.
interface Student {
readonly id: number;
}
const student: Student = {
id: 101
};
// Error:
// student.id = 102;
TypeScript reports an error because id is readonly.
An interface can contain both readonly and normal properties.
interface Student {
readonly id: number;
name: string;
age: number;
}
let student: Student = {
id: 101,
name: "Amit",
age: 20
};
student.name = "Rahul";
student.age = 21;
// student.id = 102; // Error
A string property can be readonly.
interface User {
readonly username: string;
name: string;
}
const user: User = {
username: "amit101",
name: "Amit"
};
The username should not be reassigned.
A number property can also be readonly.
interface Product {
readonly productId: number;
name: string;
}
const product: Product = {
productId: 1001,
name: "Laptop"
};
Boolean properties can also use the readonly modifier.
interface Account {
readonly verified: boolean;
username: string;
}
const account: Account = {
verified: true,
username: "amit"
};
An interface can contain multiple readonly properties.
interface Student {
readonly id: number;
readonly admissionNumber: string;
name: string;
}
const student: Student = {
id: 101,
admissionNumber: "ADM001",
name: "Amit"
};
A property can be both readonly and optional.
interface User {
readonly id: number;
readonly email?: string;
name: string;
}
const user: User = {
id: 101,
name: "Amit"
};
The email property is optional and readonly.
A property can be declared as a readonly array.
interface Student {
readonly marks: number[];
}
const student: Student = {
marks: [
80,
75,
90
]
};
The property itself cannot be reassigned.
There is an important difference between a readonly property containing an array and a readonly array.
interface Student {
readonly marks: number[];
}
const student: Student = {
marks: [80, 90]
};
// Reassignment is not allowed:
// student.marks = [70, 80];
// Array contents can still be changed:
student.marks.push(95);
The property cannot point to a different array, but the contents of the array can still be modified.
Use ReadonlyArray when the array contents should
also not be changed through that reference.
interface Student {
marks: ReadonlyArray<number>;
}
const student: Student = {
marks: [80, 90, 95]
};
// student.marks.push(100); // Error
A tuple can also be made readonly.
interface Student {
result: readonly [number, string];
}
const student: Student = {
result: [
85,
"Pass"
]
};
// student.result[0] = 90; // Error
A readonly property can contain an object.
interface Student {
readonly address: {
city: string;
pin: number;
};
}
const student: Student = {
address: {
city: "Patna",
pin: 800001
}
};
The address property cannot be replaced.
The readonly modifier applies to the property itself. It does not automatically make nested properties readonly.
interface Student {
readonly address: {
city: string;
pin: number;
};
}
const student: Student = {
address: {
city: "Patna",
pin: 800001
}
};
student.address.city = "Delhi";
// student.address = {
// city: "Delhi",
// pin: 110001
// }; // Error
A readonly property can use a union type.
interface User {
readonly id: number | string;
name: string;
}
const user: User = {
id: "USR101",
name: "Amit"
};
The property can be initialized with either a number or string, but it cannot later be reassigned.
A readonly property can also use literal types.
interface User {
readonly role: "admin" | "student";
name: string;
}
const user: User = {
role: "student",
name: "Amit"
};
An interface containing readonly properties can be passed to functions.
interface Student {
readonly id: number;
name: string;
}
function showStudent(
student: Student
) {
console.log(student.id);
console.log(student.name);
}
showStudent({
id: 101,
name: "Amit"
});
A function can read a readonly property but cannot normally reassign it.
interface Student {
readonly id: number;
name: string;
}
function updateStudent(
student: Student
) {
console.log(student.id);
student.name = "Rahul";
// student.id = 200;
// Error
}
The readonly keyword can also be used with
class properties.
class Student {
readonly id: number;
name: string;
constructor(
id: number,
name: string
) {
this.id = id;
this.name = name;
}
}
const student =
new Student(
101,
"Amit"
);
Interfaces can use readonly properties for values that a React component should only receive and read.
interface UserProps {
readonly id: number;
name: string;
}
function UserCard(
props: UserProps
) {
return (
<div>
<h3>{props.name}</h3>
<p>ID: {props.id}</p>
</div>
);
}
Readonly properties are also useful when defining React Native component data.
interface UserProps {
readonly id: number;
name: string;
}
const UserCard = (
props: UserProps
) => {
return (
<View>
<Text>
{props.name}
</Text>
<Text>
ID: {props.id}
</Text>
</View>
);
};
Readonly properties can represent values received from an API that your application should not reassign.
interface Product {
readonly id: number;
readonly createdAt: string;
name: string;
price: number;
}
const product: Product = {
id: 101,
createdAt: "2026-10-01",
name: "Laptop",
price: 50000
};
A common mistake is trying to reassign a readonly property.
interface Student {
readonly id: number;
name: string;
}
const student: Student = {
id: 101,
name: "Amit"
};
student.name = "Rahul";
// student.id = 102;
// Error: Cannot assign to 'id'
// because it is a read-only property.
Readonly is useful for values that should remain unchanged after initialization.
interface Student {
readonly id: number;
name: string;
age: number;
}
const student: Student = {
id: 101,
name: "Amit",
age: 20
};
// Allowed
student.name = "Rahul";
// Allowed
student.age = 21;
// Not allowed
// student.id = 102;
Use readonly only for properties that should not be reassigned.
The following example combines readonly, optional, array, and nested properties.
interface Student {
readonly id: number;
readonly admissionNumber: string;
name: string;
course: string;
age?: number;
phone?: string;
marks: number[];
address?: {
city: string;
pin: number;
};
}
const student: Student = {
id: 101,
admissionNumber: "ADM001",
name: "Amit",
course: "TypeScript",
age: 20,
marks: [
80,
85,
90
],
address: {
city: "Aurangabad",
pin: 824101
}
};
console.log(
student.id
);
console.log(
student.name
);
student.name =
"Rahul";
// student.id = 102;
// Error
The readonly keyword protects a property from
reassignment after initialization.
interface Student {
readonly id: number;
name: string;
}
const student: Student = {
id: 101,
name: "Amit"
};
You can read id, but you cannot normally assign
a new value to it.
readonly to prevent property reassignment.ReadonlyArray when array contents should not be changed through that reference.Question: Which keyword is used to make an interface property read-only?