Bird
Raised Fist0
Typescriptprogramming~10 mins

Readonly utility type in Typescript - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Readonly utility type
Define original object
↓
Apply Readonly<T>
↓
Create new readonly object
↓
Try to modify property
↓
Error: Cannot assign to readonly property
↓
Use readonly object safely
The Readonly utility type takes an object type and makes all its properties read-only, preventing modification.
Execution Sample
Typescript
interface Person {
  name: string;
  age: number;
}

const person: Readonly<Person> = { name: "Alice", age: 30 };
person.age = 31; // Error
This code creates a readonly person object and shows that modifying its properties causes a TypeScript error.
Execution Table
StepActionEvaluationResult
1Define interface PersonPerson has name:string and age:numberPerson type ready
2Create person as Readonly<Person>person = { name: 'Alice', age: 30 }person object created, all properties readonly
3Attempt to assign person.age = 31Check if age is writableError: Cannot assign to 'age' because it is a read-only property
4Use person properties without modificationAccess person.name and person.ageValues read successfully: 'Alice', 30
💡 Execution stops at step 3 due to TypeScript compile-time error preventing property modification
Variable Tracker
VariableStartAfter 1After 2Final
personundefinedundefined{ name: 'Alice', age: 30 } (readonly){ name: 'Alice', age: 30 } (readonly)
Key Moments - 2 Insights
Why can't I change the age property of person after using Readonly<Person>?
Readonly<Person> makes all properties read-only, so TypeScript prevents any assignment to them, as shown in step 3 of the execution_table.
Does Readonly<Person> change the original Person interface?
No, it creates a new type with all properties readonly but leaves the original Person interface unchanged, as seen in step 1 and 2.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what happens at step 3 when trying to assign person.age = 31?
AThe assignment succeeds and age becomes 31
BThe property age is deleted
CTypeScript error: Cannot assign to 'age' because it is read-only
DThe code runs but logs a warning
💡 Hint
Check the 'Result' column in step 3 of the execution_table
According to variable_tracker, what is the value of person after step 2?
AAn object with readonly properties: { name: 'Alice', age: 30 }
BAn object with writable properties
Cundefined
Dnull
💡 Hint
Look at the 'After 2' column for variable 'person' in variable_tracker
If we remove Readonly from the person declaration, how would step 3 change in the execution_table?
AStep 3 would still show an error
BStep 3 would allow assignment and update age to 31
CStep 3 would delete the person object
DStep 3 would cause a runtime exception
💡 Hint
Readonly prevents assignment errors; removing it allows property changes (see step 3 behavior)
Concept Snapshot
Readonly<T> creates a new type from T where all properties are read-only.
Syntax: Readonly<Type>
Prevents modification of properties at compile time.
Useful to protect objects from accidental changes.
Does not affect runtime, only TypeScript checks.
Full Transcript
The Readonly utility type in TypeScript takes an object type and makes all its properties read-only. This means you cannot change any property after the object is created. In the example, we define a Person interface with name and age. Then we create a person object using Readonly<Person>. Trying to assign a new value to person.age causes a TypeScript error, preventing modification. The original Person interface remains unchanged. This helps keep objects safe from accidental changes during development.

Practice

(1/5)
1. What does the Readonly utility type do in TypeScript?
easy
A. Makes all properties optional
B. Allows properties to be changed only once
C. Removes all properties from an object type
D. Makes all properties of an object type unchangeable

Solution

  1. Step 1: Understand the purpose of Readonly

    The Readonly utility type is designed to make all properties of an object type immutable, meaning they cannot be changed after initialization.
  2. Step 2: Compare with other options

    Options B, C, and D describe behaviors that are not related to Readonly. Only Makes all properties of an object type unchangeable correctly describes making properties unchangeable.
  3. Final Answer:

    Makes all properties of an object type unchangeable -> Option D
  4. Quick Check:

    Readonly = makes properties unchangeable [OK]
Hint: Readonly means no changes allowed to object properties [OK]
Common Mistakes:
  • Thinking Readonly allows one-time changes
  • Confusing Readonly with Partial or Required types
  • Believing Readonly removes properties
2. Which of the following is the correct syntax to create a readonly type from an interface User?
easy
A. type ReadonlyUser = Readonly<User>();
B. type ReadonlyUser = Readonly<User>;
C. type ReadonlyUser = readonly User;
D. type ReadonlyUser = Readonly<User>[];

Solution

  1. Step 1: Recall the syntax of Readonly utility

    The correct syntax to create a readonly version of a type or interface is Readonly<TypeName> without parentheses or array brackets.
  2. 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.
  3. Final Answer:

    type ReadonlyUser = Readonly<User>; -> Option B
  4. Quick Check:

    Readonly syntax = Readonly<Type> [OK]
Hint: Use Readonly<Type> without parentheses or brackets [OK]
Common Mistakes:
  • Adding parentheses after Readonly
  • Using lowercase 'readonly' instead of utility type
  • Confusing array of readonly with readonly type
3. What will be the output of the following TypeScript code?
interface Config {
  url: string;
  timeout: number;
}

const config: Readonly<Config> = { url: 'api.com', timeout: 5000 };

config.timeout = 3000;
console.log(config.timeout);
medium
A. Compilation error
B. 5000
C. 3000
D. undefined

Solution

  1. Step 1: Understand Readonly effect on assignment

    The Readonly type makes all properties immutable. Trying to assign a new value to config.timeout will cause a compilation error.
  2. Step 2: Check the code behavior

    The line config.timeout = 3000; is invalid and TypeScript will not compile this code, so no runtime output occurs.
  3. Final Answer:

    Compilation error -> Option A
  4. Quick Check:

    Readonly blocks property assignment = Compilation error [OK]
Hint: Readonly properties cannot be assigned new values [OK]
Common Mistakes:
  • Assuming readonly allows property changes
  • Expecting old value printed despite error
  • Confusing runtime error with compile error
4. Identify the error in this TypeScript code using 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);
medium
A. Change p.x = 15; to p = { x: 15, y: 20 };
B. Use as const instead of Readonly
C. Remove Readonly to allow property changes
D. Declare p as let instead of const

Solution

  1. Step 1: Identify why assignment fails

    The Readonly type prevents changing properties like p.x</>. The error is caused by trying to assign p.x = 15;.
  2. Step 2: Fix by removing Readonly

    Removing Readonly allows property changes. Options A, B, and D do not fix the core problem of property immutability.
  3. Final Answer:

    Remove Readonly to allow property changes -> Option C
  4. Quick Check:

    Readonly blocks property assignment; remove it to fix [OK]
Hint: Remove Readonly to allow property updates [OK]
Common Mistakes:
  • Trying to assign to readonly property instead of removing Readonly
  • Using 'as const' which makes object deeply readonly
  • Changing variable declaration without fixing immutability
5. Given this nested object type, how can you make all properties readonly including nested ones?
interface Settings {
  theme: string;
  layout: {
    header: boolean;
    footer: boolean;
  };
}
hard
A. Use a custom DeepReadonly type that recursively applies Readonly
B. Use Partial<Settings> to make properties readonly
C. Use readonly Settings keyword
D. Use Readonly<Settings> only

Solution

  1. Step 1: Understand shallow vs deep readonly

    The built-in Readonly utility only makes the top-level properties readonly. Nested objects remain mutable.
  2. Step 2: Use a recursive DeepReadonly type

    To make nested properties readonly, you need a custom type that applies Readonly recursively to all nested objects.
  3. Final Answer:

    Use a custom DeepReadonly type that recursively applies Readonly -> Option A
  4. Quick Check:

    Readonly is shallow; use DeepReadonly for nested [OK]
Hint: Readonly is shallow; use recursive type for nested readonly [OK]
Common Mistakes:
  • Assuming Readonly makes nested properties readonly
  • Using 'readonly' keyword incorrectly on types
  • Confusing Partial with Readonly
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard