In this post you’ll learn how and when to use the readonly
keyword for in TypeScript.
The readonly
property can be used in various places, for example a class
or interface
.
What is readonly in TypeScript? It’s a feature of the language that tells the TypeScript compiler to make a property readonly
. Readonly? Yes, that means you cannot reassign its value once it has been constructed. The only place a readonly
property can be assigned is inside the TypeScript constructor.
Using the readonly
keyword is an instruction to prevent compile-time reassignment, however, it makes no guarantee that your code is “safe” and cannot be reassigned elsewhere.
“Fields may be prefixed with the
readonly
modifier. This prevents assignments to the field outside of the constructor.” - TypeScript Documentation.
So when should you use readonly
? When you do not want to mutate the property value after creation.
A good example of this could be with the name
of a product:
class Product {
readonly name: string;
price: number;
constructor(name: string, price: number) {
// ✅ only assign in the constructor or property declaration above
this.name = name;
this.price = price;
}
}
If we attempt to reassign the variable, we’ll see an error:
const espresso = new Product('Espresso', 399);
// ❌ Cannot assign to 'name' because it is a read-only property.
espresso.name = 'Double Espresso';
Very helpful to have these compile-time type safety features at our disposal.
You may also use the readonly
modifier on an interface in the exact same way:
interface Product {
readonly name: string;
price: number;
}
Here’s another example for you, but using Angular, we could be using a Service which uses an Observable reference, it makes sense to consider it readonly
as well:
@Injectable()
export class ProductService {
readonly products$: Observable<Product[]> = of([]);
constructor() {}
}
A small addition to our service example code, and things become a little bit safer during development, which is especially great when working across teams and larger codebases.
I’ll say it again: marking something as readonly
will only make it safe during development and compile-time, it will make no guarantee that the value cannot be changed by others whilst in production. To do that, you’ll want to use something like Object.freeze
alongside readonly
to freeze your objects or arrays.
🏆 Check out my series of TypeScript Courses where you’ll learn TypeScript in-depth with real-world scenarios and examples to supercharge your JavaScript development.
Use the readonly
modifier for making individual properties readonly, if you want to make an entire interface readonly you can opt to use the Readonly Mapped Type, which is a fantastic feature worth exploring as well.