> ## Documentation Index
> Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt
> Use this file to discover all available pages before exploring further.

# TypeScript Readonly Field

The `readonly` modifier in TypeScript is a compile-time constraint applied to properties within classes, interfaces, and type aliases that prevents reassignment of the property's reference after its initial assignment. It enforces immutability at the property level during static type checking.

## Syntax in Classes

When applied to a class property, a `readonly` field can only be initialized in two places:

1. Inline at the point of declaration.
2. Inside the class constructor.

Any attempt to reassign the property outside of these two contexts will result in a compiler error (`TS2540`).

```typescript theme={"dark"}
class ServerConfig {
    readonly port: number = 8080; // Inline initialization
    readonly host: string;

    constructor(host: string) {
        this.host = host; // Constructor initialization (Valid)
    }

    updateConfig() {
        // this.host = "localhost"; // Error: Cannot assign to 'host' because it is a read-only property.
    }
}
```

## Syntax in Interfaces and Type Aliases

The modifier can be prefixed to properties defining object shapes. Once an object literal is cast to or inferred as this type, the compiler restricts reassignment of those specific properties.

```typescript theme={"dark"}
interface Entity {
    readonly id: string;
    createdAt: Date;
}

const user: Entity = {
    id: "uuid-1234",
    createdAt: new Date()
};

// user.id = "uuid-5678"; // Error
user.createdAt = new Date(); // Valid
```

## Technical Characteristics

**1. Shallow Immutability**
The `readonly` modifier only protects the binding (the reference) of the property. If the property holds a reference type (like an object or an array), the internal state of that object can still be mutated. It does not imply deep immutability.

```typescript theme={"dark"}
class StateManager {
    readonly flags: string[] = ["init"];
    readonly metadata: { version: number } = { version: 1 };
}

const state = new StateManager();

// state.flags = ["ready"]; // Error: Cannot reassign reference
state.flags.push("ready");  // Valid: Mutating the array

// state.metadata = { version: 2 }; // Error: Cannot reassign reference
state.metadata.version = 2;         // Valid: Mutating the object property
```

**2. Compile-Time Erasure**
`readonly` is strictly a TypeScript construct. It is completely erased during transpilation to JavaScript. It does not emit `Object.defineProperty` with `writable: false`, nor does it invoke `Object.freeze()`. Consequently, it provides zero runtime protection against reassignment.

**3. Structural Typing Bypasses**
Because TypeScript uses structural typing, a `readonly` property can be bypassed if the object is aliased to a type that does not enforce the `readonly` modifier.

```typescript theme={"dark"}
interface ReadonlyPoint {
    readonly x: number;
    readonly y: number;
}

interface MutablePoint {
    x: number;
    y: number;
}

const origin: ReadonlyPoint = { x: 0, y: 0 };
const reference: MutablePoint = origin; // Valid structural assignment

reference.x = 10; // Mutates the underlying object, bypassing the readonly constraint of 'origin'
```

## Related Constructs

* **`Readonly<T>` Utility Type:** A mapped type that iterates over all properties of type `T` and applies the `readonly` modifier to them.
* **`readonly` Arrays/Tuples:** Applied to array types (e.g., `readonly string[]` or `ReadonlyArray<string>`) to remove mutating methods like `push`, `pop`, and `splice` from the type definition.

<div
  style={{ 
display: "flex", 
justifyContent: "space-between", 
alignItems: "center", 
maxWidth: "754px", 
padding: "1rem 0",
marginBottom: "24px"
}}
>
  <span style={{ fontWeight: "bold", fontSize: "1.25rem", color: "var(--tw-prose-headings)", fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif" }}>Tired of Poor TypeScript Skills? Fix That With Deep Grasping!</span>

  <a
    href="https://syntblaze.com"
    target="_blank"
    style={{ 
  marginLeft: "24px",
  textDecoration: "none", 
  backgroundColor: "#007AFF",
  color: "#ffffff", 
  padding: "6px 16px", 
  borderRadius: "16px",
  fontSize: "0.9rem",
  fontWeight: "600",
  textAlign: "center",
  transition: "background-color 0.2s ease"
}}
  >
    Learn More
  </a>
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/skill-tracking.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=b9b0305c93bb501c9e767b5c76c88835" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/skill-tracking.png" />

  <img src="https://mintcdn.com/syntblazellc/23tyuOzaWS88qFlc/images/nuggets.png?fit=max&auto=format&n=23tyuOzaWS88qFlc&q=85&s=c86c80197299762989e9b882419b2109" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/nuggets.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/bite-sized-exercises.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=a65f9a38c37ff28ab73ed783c53c60e3" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/bite-sized-exercises.png" />
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap", marginTop: "12px" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/mastery-chain.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=748a1763454713e679260fbb95f154a2" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/mastery-chain.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-previews.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=242f61448ff5dd6deaaab2dccc13b507" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-previews.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-explanations.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=cf0fc1c31f9cd0fc26716781be05fbc9" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-explanations.png" />
</div>
