0Pricing
TypeScript Academy · Lektion

Muster für tiefe Unveränderlichkeit

Erreichen Sie mit rekursiven Typen tief verschachtelte readonly-Strukturen.

Muster für tiefe Unveränderlichkeit ist eine kostenlose TypeScript Academy-Lektion auf CoddyKit. Dies ist Lektion 4 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des TypeScript Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der TypeScript Academy-Kurs umfasst insgesamt 4 Lektionen.

Flache und tiefe Unveränderlichkeit

Der readonly-Modifikator ist flach: Er schützt die oberste Ebene, aber keine verschachtelten Objekte. Tiefe Unveränderlichkeit bedeutet, dass jede Ebene bis hinunter readonly ist. Dafür ist zusätzlicher Aufwand erforderlich.

interface State { readonly user: { name: string }; }
const s: State = { user: { name: 'Ada' } };
// s.user = {...}; // Error (shallow protection)
s.user.name = 'Grace'; // allowed! nested field is mutable
console.log(s.user.name);

Warum flach nicht ausreicht

Bei Zustandsverwaltung und gemeinsam genutzten Daten lässt flaches readonly verschachtelte Felder ungeschützt. Eine einzige übersehene Änderung tief in einer Struktur kann subtile, schwer nachzuverfolgende Fehler verursachen.

interface Config { readonly db: { host: string; port: number }; }
const c: Config = { db: { host: 'localhost', port: 5432 } };
c.db.port = 9999; // mutates nested data despite readonly
console.log(c.db.port);

Ein rekursiver DeepReadonly-Typ

Wir können einen Mapped Type erstellen, der readonly rekursiv anwendet. DeepReadonly<T> durchläuft jede Eigenschaft und steigt, wenn es sich um ein Objekt handelt, rekursiv in dieses hinein.

type DeepReadonly<T> = {
  readonly [K in keyof T]: T[K] extends object
    ? DeepReadonly<T[K]>
    : T[K];
};
console.log('DeepReadonly defined');

DeepReadonly anwenden

Wenn Sie einen Typ mit DeepReadonly umschließen, werden auch verschachtelte Eigenschaften unveränderlich. Nun kann selbst s.user.name nicht neu zugewiesen werden – der Schutz reicht bis in die tiefste Ebene.

type DeepReadonly<T> = {
  readonly [K in keyof T]: T[K] extends object
    ? DeepReadonly<T[K]>
    : T[K];
};
type State = DeepReadonly<{ user: { name: string } }>;
const s: State = { user: { name: 'Ada' } };
// s.user.name = 'x'; // Error now
console.log(s.user.name);

So funktioniert der Mapped Type

[K in keyof T] durchläuft jeden Schlüssel. Das Präfix readonly sperrt jeden einzelnen. Die Bedingung T[K] extends object ? ... : T[K] entscheidet, ob die Rekursion fortgesetzt oder bei einem primitiven Typ beendet wird.

type DeepReadonly<T> = {
  readonly [K in keyof T]: T[K] extends object
    ? DeepReadonly<T[K]>
    : T[K];
};
type Cfg = DeepReadonly<{ a: number; b: { c: string } }>;
const cfg: Cfg = { a: 1, b: { c: 'x' } };
console.log(cfg.a, cfg.b.c);

Schutz nur zur Compilezeit

DeepReadonly setzt Unveränderlichkeit im Typsystem durch, nicht zur Laufzeit. Das JavaScript-Objekt ist über untypisierte Pfade technisch weiterhin veränderbar – Ihr typisierter Code ist jedoch vollständig geschützt.

// Type-level immutability does not freeze the runtime object.
// For runtime guarantees, combine it with Object.freeze.
console.log('Types guard your code; freeze guards runtime');

Verschachtelte Objekte zur Laufzeit einfrieren

Für tatsächliche Unveränderlichkeit zur Laufzeit verwenden Sie Object.freeze. Dadurch wird verhindert, dass Eigenschaften hinzugefügt, entfernt oder geändert werden – wie bei readonly gilt dies standardmäßig jedoch nur für die oberste Ebene.

const config = Object.freeze({ host: 'localhost', port: 8080 });
console.log(config.port);
// In strict mode, config.port = 1 throws; otherwise silently ignored.

Ein Helfer zum tiefen Einfrieren

Um zur Laufzeit vollständig einzufrieren, durchlaufen Sie verschachtelte Objekte rekursiv und frieren jedes einzelne ein. Dies ergänzt das typbasierte DeepReadonly auf natürliche Weise und sorgt für durchgängige Unveränderlichkeit.

function deepFreeze<T>(obj: T): T {
  Object.values(obj as any).forEach((v) => {
    if (v && typeof v === 'object') deepFreeze(v);
  });
  return Object.freeze(obj);
}
const frozen = deepFreeze({ a: { b: 1 } });
console.log(frozen.a.b);

Unveränderlichkeit für sichereren Zustand

Tiefe Unveränderlichkeit ist die Grundlage für vorhersehbaren Zustand. Wenn Daten nicht direkt verändert werden können, müssen Aktualisierungen neue Objekte erstellen, wodurch Änderungen eindeutig und leicht nachzuverfolgen sind.

const state = { count: 0, user: { name: 'Ada' } };
// Immutable update: create a new object instead of mutating
const next = { ...state, count: state.count + 1 };
console.log(state.count, next.count);

Muster für unveränderliche Aktualisierungen

Mit readonly-Daten erzeugen Sie über Spread-Syntax neue Versionen. Jede Aktualisierung ist ein neues Objekt, sodass vorherige Zustände erhalten bleiben – besonders wertvoll für Rückgängig-Funktionen, Time-Travel-Debugging und die Erkennung von Änderungen.

type State = { readonly items: readonly string[] };
const s: State = { items: ['a'] };
const updated: State = { items: [...s.items, 'b'] };
console.log(s.items, updated.items);

Typ- und Laufzeitsicherheit kombinieren

Der sicherste Ansatz verwendet beides: DeepReadonly für Garantien zur Compilezeit und deepFreeze für die Durchsetzung zur Laufzeit. Zusammen machen sie versehentliche Änderungen nahezu unmöglich.

function freeze<T>(obj: T): T {
  return Object.freeze(obj);
}
const settings = freeze({ theme: 'dark', version: 2 });
console.log(settings.theme, settings.version);

Schnelltest

Testen Sie Ihr Verständnis von tiefer Unveränderlichkeit.

Zusammenfassung: Tiefe Unveränderlichkeit

Sie haben gelernt, dass:

  • readonly flach ist; verschachtelte Felder bleiben veränderlich.
  • ein rekursiver DeepReadonly<T>-Mapped-Type readonly auf jeder Ebene anwendet.
  • es nur zur Compilezeit gilt; verwenden Sie Object.freeze (rekursiv) für die Durchsetzung zur Laufzeit.
  • Unveränderlichkeit über Muster mit Kopieren-bei-Aktualisierung einen sicheren, vorhersehbaren Zustand ermöglicht.

Damit ist der TypeScript-Academy-Track zu fortgeschrittenen Typen und Unveränderlichkeit abgeschlossen.

type State = { readonly value: number };
const s: State = { value: 1 };
const next: State = { ...s, value: s.value + 1 };
console.log(s.value, next.value);

Häufig gestellte Fragen

Ist die Lektion „Muster für tiefe Unveränderlichkeit“ kostenlos?

Ja — der vollständige Text von „Muster für tiefe Unveränderlichkeit“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des TypeScript Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der TypeScript Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Muster für tiefe Unveränderlichkeit“?

Erreichen Sie mit rekursiven Typen tief verschachtelte readonly-Strukturen. Du übst TypeScript Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um TypeScript Academy zu starten?

Keine Vorkenntnisse erforderlich. TypeScript Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 4 von 4.

Wie lange dauert die Lektion „Muster für tiefe Unveränderlichkeit“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser TypeScript Academy-Lektion Code schreiben und ausführen?

Ja. Jede TypeScript Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. readonly-Eigenschaften
  2. readonly-Arrays und Tupel
  3. ReadonlyArray und ReadonlyMap
  4. Muster für tiefe Unveränderlichkeit
← Zurück zu TypeScript Academy