TypeScript provides several utility types that makes working with types easier. Today I want to take a look at the Readonly<T> type.
The Readonly<T>
type makes all the properties in T
become read-only, it does so by annotating each field with the readonly
keyword while mapping:
type Readonly<T> = { | |
readonly [P in keyof T]: T[P]; | |
}; |
It is useful to make an immutable version of a type. Here is an example:
interface Product { | |
name: string; | |
} | |
const playstation: Product = { | |
name: "Playstation 5" | |
} | |
const xbox: Readonly<Product> = { | |
name: "XBOX One", | |
}; | |
// Throws a compiler error | |
xbox.name = "XBOX 360"; | |
const immutableProduct:Readonly<Product> = playstation; | |
// Throws a compiler error | |
immutableProduct.name = "Playstation 4"; |
If I load this code in the TypeScript playground, I get the following compiler errors:
I was hoping that this TypeScript code in someway was transpiled to an Object.Freeze() implementation but this turns out not to be the case. The TypeScript Readonly<T>
type provides only static typing immutability(in favor of performance) whereas Object.Freeze()
provides runtime immutability.
It is however possible to combine the two: