Readonly Properties in TypeScript

Readonly is a typescript keyword that makes the property read-only in a class, interface, or type alias. We make a property read-only by prefixing the property as readonly. We can assign a value to the readonly property only when initializing the object or within a constructor of the class. Any other assignments will result in a compiler error.

Creating Read-Only Properties in TypeScript

To create a read-only property, we prefix the keyword readonly before the property name.

In the example below the price property is marked as readonly. We can assign a value to the price property when we initialize the object. However, we cannot change its value afterward. If we try to assign a value compiler throws an Cannot assign to 'price' because it is a read-only property error.

Creating Objects with readonly property

readonly property in Interface

readonly property in Type Alias

Class and readonly property

In a class, we can assign the value to the readonly property only inside the construction function

Readonly is a read-only reference to a value

We cannot assign a new value to readonly property. But if the value is an object, you can modify the object itself.

The person interface below has an address property that is readonly. We create a person object from it.

We cannot assign a new address to the address property because address is readonly.

But address itself is an object and contains properties. You can change them

You can solve this problem by making all the properties of interface Address as readonly

Types that differ only in their readonly attributes are mutually assignable

This example has two similar interfaces RW & RO with value property. Value property has a readonly attribute in RO.

We create a variable ro using the interface RO. Since the value is readonly we cannot assign a value to it.

We create rw variable using the RW interface and assign ro to it. Now both ro & rw points to the same object. Now you can assign value to the value property using the variable rw effectively bypassing the readonly attribute.

You can follow this issue here

Readonly exists only in compile time

The readonly is specific to TypeScript and does not exist in run time. Typescript compiler uses it to check for illegal property assignments in compile time. So the variable does not have any protection in the run-time. Once the code is transpiled into JavaScript readonly is gone.

Readonly vs. const

It may appear that the const keyword in Typescript is similar to readonly but they are not. Both have several differences

const apply to variables only. readonly for properties

Trying to define price as const throws an error. In fact, you cannot use let, var & const in property declarations. We use const to declare variables and not properties.

const is used to create variables. In this example, const keyword is used to create the prd variable. You cannot assign a new value to the prd variable. But you can modify the object that the const variable points to.

Similarly, you cannot prefix a variable with readonly or declare a variable with readonly

const is runtime check readonly is compile-time check

readonly is only a compile-time check. The compiler removes it when it compiles it into JavaScript.

const is a JavaScript construct. Hence exists in run time. You cannot assign a new value to const variable ever. But note that the object pointed by the const can be modified.

Make all properties readonly in an existing type

Readonly utility type creates a new type from an existing type with all properties of the new type set to readonly. This means that we cannot assign values to the properties of any object which we create from it.

In this example, we create two new objects from the interface Product. The product2 is created after transforming the interface using the Readonly utility. Hence while assigning a value to any of the properties of the product2 compiler throws an error.

In this example, the address is readonly along with all of its properties.

vs Object.freeze

JavaScript’s object.freeze method freezes an object. You cannot assign a new value to an existing property of a frozen object effectively making it a read-only property. Also, you cannot add or remove a property from the frozen object. It is a run-time check and no code can change the value of the property.

While Typescripts Readonly is only a compile-time check. Other libraries can modify the value of the Read-only properties

In this example, we create a readonly product1 object. While the compiler will not allow us to assign a value to price, you override it by casting it to any and assigning a value.

But if you freeze the object and try to do the same, the compiler won’t object. But the JavaScript throws a runtime error and execution stops.

Hence use object.freeze if you want to ensure no changes to the value both in run time or in compile-time and use Readonly if the compile-time check is sufficient.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top