Fixing the TypeScript Error: Cannot assign to 'property' because it is a read-only property

beginner๐Ÿ”ต TypeScript2026-04-06| TypeScript 3.0+, VS Code, Node.js environment

Error Message

Cannot assign to 'property' because it is a read-only property.
#typescript#frontend#web-development#coding-tips

TL;DR: The Fast Fixes

Stuck on a deadline? Use one of these three methods to get your code running immediately:

  • Edit the source: Find the interface or type and delete the readonly keyword.
  • Force the change: Use a type assertion to bypass the check: (myObject as any).property = 'new value';.
  • Drop the const: If you defined your object with as const, remove that suffix to make the object mutable again.

Why TypeScript Blocks Your Edit

You'll run into this error when the compiler spots an attempt to change a value that was explicitly marked as immutable. TypeScript does this to prevent bugs caused by unexpected state changes. Usually, the culprit is one of these three scenarios:

  • The property in the interface or type has a readonly prefix.
  • The object was declared with a Const Assertion (as const), making every field immutable.
  • You are trying to update a class property that was marked readonly outside of the constructor.
interface User {
  readonly id: number;
  name: string;
}

const user: User = { id: 101, name: 'Alice' };
// โŒ Error: Cannot assign to 'id' because it is a read-only property.
user.id = 202; 

4 Ways to Resolve the Error

1. Modify the Interface Definition

The simplest approach is to allow the property to change. If your logic requires updating a value, like a retryCount or a lastLogin timestamp, the readonly flag shouldn't be there in the first place.

// Before: Immutable
interface AppConfig {
  readonly port: number;
}

// After: Mutable
interface AppConfig {
  port: number;
}

2. Use a Type Assertion (The Escape Hatch)

You might encounter this when using third-party libraries where you can't edit the source code. In these cases, you can tell TypeScript to "trust you" by casting the object. This is common in unit tests when you need to mock specific data states.

interface Profile {
  readonly email: string;
}

const userProfile: Profile = { email: 'test@example.com' };

// Option A: Cast to any
(userProfile as any).email = 'new@example.com';

// Option B: Create a Writable utility type
type Writable<T> = { -readonly [P in keyof T]: T[P] };
(userProfile as Writable<Profile>).email = 'admin@internal.com';

3. Remove "as const" Assertions

Using as const is a handy way to create literal types, but it locks down every nested property. If you need to change a theme setting from 'dark' to 'light', don't use a const assertion for the whole object.

// This object is 100% locked
const UI_SETTINGS = {
  theme: 'dark',
  sidebarWidth: 250
} as const;

// UI_SETTINGS.theme = 'light'; // โŒ This will fail

// Fix: Use a standard object or a specific type
const UI_SETTINGS = {
  theme: 'dark',
  sidebarWidth: 250
};

4. Convert Readonly Arrays

Methods like push(), pop(), or splice() will trigger this error if the array is defined as readonly string[]. Since these methods mutate the original array, TypeScript blocks them. To fix this, create a mutable copy using the spread operator.

const roles: readonly string[] = ['admin', 'editor'];

// roles.push('viewer'); // โŒ Error

// Fix: Spread into a new array
const activeRoles = [...roles];
activeRoles.push('viewer'); // โœ… Works perfectly

How to Double-Check Your Work

Once you apply a fix, verify it with these three steps:

  • Look for the red line: VS Code should immediately remove the red squiggly underline.
  • Run a build: Fire up your terminal and run npx tsc. If it finishes without errors, your fix is type-safe.
  • Verify the JS: If you used as any, remember that TypeScript won't help you at runtime. Check your logs or browser console to ensure the value actually updated.

Pro Tip: Stay Immutable When Possible

Don't just delete readonly to make an error go away. Immutability makes your code easier to debug. If you're working in React or Redux, instead of forcing a change on a read-only property, always return a new object: const updated = { ...oldObject, status: 'active' };. This keeps your data flow predictable and avoids side effects.

Related Error Notes