Readonly utility type in Typescript - Time & Space Complexity
We want to understand how the time it takes to use the Readonly utility type changes as the size of the object grows.
Specifically, how does making an object readonly affect the number of operations when the object has many properties?
Analyze the time complexity of the following code snippet.
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
interface User {
name: string;
age: number;
email: string;
}
const user: Readonly<User> = {
name: "Alice",
age: 30,
email: "alice@example.com"
};
This code creates a readonly version of a User object by applying the Readonly utility type to all its properties.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The mapped type loops over each property key in the object type.
- How many times: Once for each property in the object (for example, 3 times for User).
As the number of properties in the object grows, the number of operations grows in the same way.
| Input Size (n) | Approx. Operations |
|---|---|
| 3 | 3 (one per property) |
| 10 | 10 |
| 100 | 100 |
Pattern observation: The operations increase directly with the number of properties, growing in a straight line.
Time Complexity: O(n)
This means the time to create a readonly type grows linearly with the number of properties in the object.
[X] Wrong: "Making an object readonly happens instantly no matter how big it is."
[OK] Correct: The type system processes each property one by one, so more properties mean more work.
Understanding how utility types like Readonly work helps you reason about type transformations and their costs, a useful skill in real projects and interviews.
"What if we changed Readonly to make only some properties readonly? How would the time complexity change?"
Practice
Readonly utility type do in TypeScript?Solution
Step 1: Understand the purpose of
TheReadonlyReadonlyutility type is designed to make all properties of an object type immutable, meaning they cannot be changed after initialization.Step 2: Compare with other options
Options B, C, and D describe behaviors that are not related toReadonly. Only Makes all properties of an object type unchangeable correctly describes making properties unchangeable.Final Answer:
Makes all properties of an object type unchangeable -> Option DQuick Check:
Readonly = makes properties unchangeable [OK]
- Thinking Readonly allows one-time changes
- Confusing Readonly with Partial or Required types
- Believing Readonly removes properties
User?Solution
Step 1: Recall the syntax of Readonly utility
The correct syntax to create a readonly version of a type or interface isReadonly<TypeName>without parentheses or array brackets.Step 2: Analyze each option
type ReadonlyUser = Readonly<User>; uses the correct generic syntax. type ReadonlyUser = Readonly<User>(); incorrectly uses parentheses. type ReadonlyUser = readonly User; uses lowercase 'readonly' which is a keyword for arrays or tuples, not for types. type ReadonlyUser = Readonly<User>[]; creates an array of readonly users, which is different.Final Answer:
type ReadonlyUser = Readonly<User>; -> Option BQuick Check:
Readonly syntax = Readonly<Type> [OK]
- Adding parentheses after Readonly
- Using lowercase 'readonly' instead of utility type
- Confusing array of readonly with readonly type
interface Config {
url: string;
timeout: number;
}
const config: Readonly<Config> = { url: 'api.com', timeout: 5000 };
config.timeout = 3000;
console.log(config.timeout);Solution
Step 1: Understand Readonly effect on assignment
TheReadonlytype makes all properties immutable. Trying to assign a new value toconfig.timeoutwill cause a compilation error.Step 2: Check the code behavior
The lineconfig.timeout = 3000;is invalid and TypeScript will not compile this code, so no runtime output occurs.Final Answer:
Compilation error -> Option AQuick Check:
Readonly blocks property assignment = Compilation error [OK]
- Assuming readonly allows property changes
- Expecting old value printed despite error
- Confusing runtime error with compile error
Readonly and fix it:interface Point {
x: number;
y: number;
}
const p: Readonly<Point> = { x: 10, y: 20 };
p.x = 15;
console.log(p.x);Solution
Step 1: Identify why assignment fails
TheReadonlytype prevents changing properties likep.x</>. The error is caused by trying to assignp.x = 15;.Step 2: Fix by removing Readonly
RemovingReadonlyallows property changes. Options A, B, and D do not fix the core problem of property immutability.Final Answer:
Remove Readonly to allow property changes -> Option CQuick Check:
Readonly blocks property assignment; remove it to fix [OK]
- Trying to assign to readonly property instead of removing Readonly
- Using 'as const' which makes object deeply readonly
- Changing variable declaration without fixing immutability
interface Settings {
theme: string;
layout: {
header: boolean;
footer: boolean;
};
}Solution
Step 1: Understand shallow vs deep readonly
The built-inReadonlyutility only makes the top-level properties readonly. Nested objects remain mutable.Step 2: Use a recursive DeepReadonly type
To make nested properties readonly, you need a custom type that appliesReadonlyrecursively to all nested objects.Final Answer:
Use a custom DeepReadonly type that recursively applies Readonly -> Option AQuick Check:
Readonly is shallow; use DeepReadonly for nested [OK]
- Assuming Readonly makes nested properties readonly
- Using 'readonly' keyword incorrectly on types
- Confusing Partial with Readonly
Ready to prove it?
Pass the test and this pattern moves unknown
