TypeScript Readonly Utility Type
📝 Table Of Contents
☕️ Summary
The Readonly<Type>
utility type constructs a type with all properties of Type
set to readonly
where the properties of the newly constructed type cannot be
reassigned.
Continuing on with our guide through utility types, we're going to create another function called freezeUser
that will freeze
an object with the JavaScript Object.freeze()
method and return a user object with readonly
properties.
This will also demonstrate the difference between compile-time immutability and run-time immutability.
▶️ Code Sandbox Example
🛠 How It Works
So, let's take a look at the freezeUser
function we've created.
// User.tsx
export function freezeUser(user: User): Readonly<User> {
Object.freeze(user);
return user;
}
We take in a parameter user
of type User
and the return type of the function is Readonly<User>
which is a newly constructed User
with
all properties set to readonly
. This means that it is readonly
to the Typescript compiler, so the compiler will warn us if we attempt
to reassign any of the properties.
Also, in the freezeUser
function, we use Object.freeze()
and return the frozen object which also will not update
the age of user4 at runtime.
// App.tsx
let user4 = freezeUser(user3);
user4.age = 55;
// Cannot assign to 'lastName' because it is a read-only property.
But then what if we reassign user4 to a new object that is not frozen, yet still readonly?
Let's re-use the updateUser
function from the first guide for using the Partial utility type ↗ which
will reassign user4 to an object that is no longer frozen.
// App.tsx
// Now we're reassigning user4 to a new object that is returned
// from the updateUser() function which means it's no longer frozen.
user4 = updateUser(user4, { firstName: "Alien" });
user4.lastName = "Musk";
// Cannot assign to 'age' because it is a read-only property.
We still get the compiler warning us that user4.lastname is read-only but this still does not stop that value of those properties from changing at run-time though. The UI will still update the value at runtime.
🧠 Quiz Question
Given an interface Block
with 2 properties hash
and message
:
interface Block = {
hash: string;
message?: string;
};
If we wanted to define a new type StrictBlock
with Readonly<Block>
like this:
type StrictBlock = Readonly<Block>;
Which of the following is true of StrictBlock
?
Test your knowledge 🧠