Kaum ein Interface in einer realen Codebasis kommt ohne optionale oder schreibgeschützte Felder aus. Optional, weil API-Antworten, Form-Inputs und Konfigurations-Objekte selten alle Felder zugleich tragen — und Readonly, weil viele Daten nach ihrer Konstruktion nicht mehr verändert werden dürfen, ohne irgendwo einen Bug zu erzeugen. TypeScript bietet für beide Anliegen eine sehr kompakte Syntax — das Fragezeichen hinter dem Property-Namen und das Schlüsselwort readonly davor — aber hinter dieser Schlichtheit verbergen sich erstaunlich viele Feinheiten: Was unterscheidet name?: string von name: string | undefined? Wie tief greift readonly? Was macht das Flag exactOptionalPropertyTypes, und warum solltest du es in modernen Projekten aktivieren? Dieser Artikel klärt alle diese Fragen mit dichten Beispielen, zeigt die typischen Kombinationen — readonly id?: number an API-Grenzen — und benennt die Anti-Patterns, die jede Codebasis irgendwann ausbremsen.

Optional Properties — die ?-Syntax

Eine optionale Property wird mit einem Fragezeichen direkt hinter dem Namen markiert. Damit signalisiert das Interface: dieses Feld kann vorhanden sein, muss es aber nicht. Auf der Aufrufseite darfst du das Property weglassen, ohne dass der Compiler protestiert; auf der Lese-Seite hingegen behandelt TypeScript den Wert als Type | undefined — denn ein nicht-gesetztes Property liefert beim Zugriff undefined zurück.

ts user-settings.ts
// Klassisches Beispiel: ein Settings-Objekt, bei dem fast jedes Feld optional ist.
interface UserSettings {
    userId: number;            // Pflichtfeld — jede Sitzung braucht eine ID.
    theme?: "light" | "dark";  // optional — Fallback auf Systempraeferenz.
    language?: string;         // optional — Fallback auf Browser-Sprache.
    notifications?: boolean;   // optional — Default ist projektabhaengig.
}

// Auf der Aufruferseite duerfen alle Optional-Felder fehlen.
const minimal: UserSettings = { userId: 1 };
const verbose: UserSettings = {
    userId: 2,
    theme: "dark",
    language: "de",
    notifications: true,
};

// Beim Lesen ist der Typ jeweils "Type | undefined" — das erzwingt
// einen Default oder einen Null-Check.
function describe(s: UserSettings): string {
    const theme = s.theme ?? "light";          // Nullish-Coalescing als Default
    const lang  = s.language ?? "en";          // dito
    const notif = s.notifications ?? false;    // dito
    return `User ${s.userId}: ${theme}/${lang}, notif=${notif}`;
}

console.log(describe(minimal));
console.log(describe(verbose));
Output
User 1: light/en, notif=false
User 2: dark/de, notif=true

Zwei Dinge sind hier zentral. Erstens: das Fragezeichen erlaubt das Weglassen beim Konstruieren des Objekts — kein roter Schlangenlinien-Hinweis, kein erzwungener undefined-Eintrag. Zweitens: beim Lesen musst du dich darauf einstellen, dass der Wert fehlen kann. s.theme ist nicht "light" | "dark", sondern "light" | "dark" | undefined. Das Nullish-Coalescing-Operator ?? ist der idiomatische Weg, dieser Realität zu begegnen.

Optional vs. | undefined — der subtile Unterschied

Auf den ersten Blick erscheinen name?: string und name: string | undefined deckungsgleich — in beiden Fällen kann am Ende undefined herauskommen. Tatsächlich gibt es aber einen Unterschied, der dich beißt, sobald du Objekt-Literale konstruierst: das Fragezeichen erlaubt es, das Property komplett wegzulassen; die explizite Union erzwingt, dass das Property vorhanden ist — wenn auch eventuell mit dem Wert undefined.

ts optional-vs-undefined.ts
// Variante A: optional via Fragezeichen.
interface A {
    name?: string;
}

// Variante B: explizit Pflicht, aber Wert kann undefined sein.
interface B {
    name: string | undefined;
}

// Bei A darf das Feld komplett fehlen.
const a1: A = {};                       // OK
const a2: A = { name: "Anna" };         // OK
const a3: A = { name: undefined };      // OK (ohne exactOptionalPropertyTypes)

// Bei B muss das Feld vorhanden sein — auch wenn nur als undefined.
// const b1: B = {};                    // Fehler: Property 'name' fehlt.
const b2: B = { name: "Anna" };         // OK
const b3: B = { name: undefined };      // OK — Property ist da, Wert ist undefined.

// Der "in"-Operator deckt den Unterschied auf:
console.log("name" in a1);              // false — Property existiert gar nicht
console.log("name" in b3);              // true  — Property existiert, Wert ist undefined

Das ist kein akademischer Spitzfindigkeits-Punkt. Sobald du Code schreibst, der über Object.keys(), in-Operator, Reflection oder JSON.stringify() arbeitet, macht es einen messbaren Unterschied, ob ein Property fehlt oder mit undefined gesetzt ist. JSON.stringify({ name: undefined }) liefert "{}" — das Property verschwindet im Wire-Format. Wer das nicht weiß, debuggt eines Tages eine sehr seltsame API-Diskrepanz.

exactOptionalPropertyTypes

Mit TypeScript 4.4 kam ein striktes Flag, das genau diese Unschärfe abschafft: exactOptionalPropertyTypes. Aktiviert es, und das Fragezeichen bedeutet plötzlich nicht mehr „darf fehlen ODER undefined sein", sondern ausschließlich „darf fehlen". Wer das Property explizit auf undefined setzen möchte, muss undefined selbst in die Typ-Definition aufnehmen.

ts exact-optional.ts
// tsconfig.json:
// {
//   "compilerOptions": {
//     "strict": true,
//     "exactOptionalPropertyTypes": true
//   }
// }

interface UserDefaults {
    // Das Fehlen des Werts bedeutet hier explizit "System-Default".
    colorThemeOverride?: "dark" | "light";
}

const settings: UserDefaults = {};

settings.colorThemeOverride = "dark";       // OK
settings.colorThemeOverride = "light";      // OK
// settings.colorThemeOverride = undefined; // Fehler mit exactOptionalPropertyTypes:
//   Type 'undefined' is not assignable to type '"dark" | "light"'.
//   Consider adding 'undefined' to the type of the target.

// Wer "undefined" als gueltigen Wert haben will, schreibt es hin:
interface UserDefaultsLoose {
    colorThemeOverride?: "dark" | "light" | undefined;
}
const loose: UserDefaultsLoose = { colorThemeOverride: undefined }; // OK

Warum lohnt sich das? Drei Argumente. Erstens: dein Code beschreibt damit präziser, was er wirklich meint. Wenn ein Optional-Feld bei dir bedeutet „nicht gesetzt = System-Default", dann ist das aktive Setzen auf undefined semantisch etwas anderes und sollte ein Compile-Fehler sein. Zweitens: serialisierte Form (JSON, Wire-Format) und in-memory-Form bleiben konsistent, weil niemand „aus Versehen" eine Property als undefined deklariert. Drittens: das Flag deckt schlampige Default-Initialisierungen auf, bei denen jemand obj.field = undefined schreibt, statt das Property gar nicht zu setzen. Faustregel für neue Projekte: an, zusammen mit strict: true.

Optional in Funktions-Parametern

Das Fragezeichen funktioniert nicht nur in Interfaces, sondern auch direkt an Funktions-Parametern. Die Regel: optionale Parameter müssen am Ende stehen, weil JavaScript Funktionen positional aufruft und kein Parameter „übersprungen" werden kann. Eine echte Alternative ist der Default-Wert, der einen Parameter implizit optional macht und gleichzeitig den Fallback definiert.

ts optional-params.ts
// Variante 1 — klassisches Fragezeichen.
function greet(name: string, greeting?: string): string {
    // greeting ist hier "string | undefined" — Default haendisch wählen.
    return `${greeting ?? "Hallo"}, ${name}!`;
}

// Variante 2 — Default-Wert macht den Parameter implizit optional.
function greet2(name: string, greeting: string = "Hallo"): string {
    // greeting ist hier garantiert "string" — der Default greift, wenn nichts übergeben wird.
    return `${greeting}, ${name}!`;
}

console.log(greet("Anna"));            // greeting = undefined -> "Hallo, Anna!"
console.log(greet("Anna", "Servus"));  // "Servus, Anna!"
console.log(greet2("Anna"));           // Default greift -> "Hallo, Anna!"

// Anti-Pattern: optional vor Pflicht. TypeScript verhindert das:
// function bad(x?: number, y: number) { ... }
// Fehler: A required parameter cannot follow an optional parameter.
Output
Hallo, Anna!
Servus, Anna!
Hallo, Anna!

Praktische Faustregel: bei einem oder zwei optionalen Parametern reicht die Default-Wert-Variante völlig — sie ist kürzer und der Body braucht keine Null-Checks. Sobald du drei oder mehr optionale Parameter hast, oder die Parameter zueinander in semantischer Abhängigkeit stehen, kippt die Lesbarkeit. Ab dann ist ein Options-Objekt mit Optional-Properties die klar bessere Wahl: man kann beim Aufruf benannt einzelne Felder setzen, ohne sich um Reihenfolge zu kümmern.

Readonly Properties — der readonly-Modifier

Mit dem Schlüsselwort readonly vor einem Property erklärst du es zum schreibgeschützten Feld. Du darfst es weiterhin lesen, du darfst beim Konstruieren des Objekts initial einen Wert eintragen — aber nach der Initialisierung weigert sich der Compiler, einen erneuten Schreibzugriff zuzulassen. Wichtig: dieser Schutz wirkt rein zur Compile-Zeit. Zur Laufzeit gibt es kein Object.freeze, kein Proxy, keinen Mechanismus, der eine Mutation tatsächlich verhindert — readonly ist eine Aussage über deine Absicht, nicht eine technische Sperre.

ts readonly-config.ts
// Klassischer Anwendungsfall: ein Konfigurations-Objekt, das beim Start
// gelesen und dann nie wieder verändert werden soll.
interface AppConfig {
    readonly apiBaseUrl: string;
    readonly maxRetries: number;
    readonly environment: "development" | "staging" | "production";
}

const config: AppConfig = {
    apiBaseUrl: "https://api.example.com",
    maxRetries: 3,
    environment: "production",
};

// Lesen — kein Problem.
console.log(config.apiBaseUrl);

// Schreiben — Compile-Fehler:
// config.apiBaseUrl = "https://hack.example.com";
// Fehler: Cannot assign to 'apiBaseUrl' because it is a read-only property.

// Auch das Loeschen wird abgewiesen:
// delete config.maxRetries;
// Fehler: The operand of a 'delete' operator cannot be a readonly property.

Der Schutz greift bei Zuweisung, delete und auch bei Increment/Decrement (config.maxRetries++). Er greift nicht, wenn du das Objekt über einen Alias mit Person-Typ (ohne readonly) erreichst — TypeScript ignoriert readonly bei der Strukturtyp-Kompatibilität, sodass eine schreibbare Referenz auf dasselbe Objekt weiterhin mutiert werden darf. Das ist ein bewusstes Designloch, das du kennen solltest, bevor du dich auf readonly als Sicherheitsgarantie verlässt.

Readonly ist flach, nicht tief

Die zweite große Stolperfalle: readonly wirkt nur auf die direkte Property, nicht auf verschachtelte Strukturen. Markierst du home.resident als readonly, darfst du home.resident selbst nicht neu zuweisen — aber home.resident.age++ ist weiterhin erlaubt, weil das age-Feld des inneren Objekts nicht von readonly betroffen ist.

ts readonly-shallow.ts
interface Home {
    readonly resident: { name: string; age: number };
}

const home: Home = { resident: { name: "Anna", age: 30 } };

// Verbotene direkte Re-Zuweisung:
// home.resident = { name: "Bob", age: 40 };
// Fehler: Cannot assign to 'resident' because it is a read-only property.

// Aber das hier ist erlaubt — die Mutation findet eine Ebene tiefer statt:
home.resident.age++;
console.log(home.resident); // { name: "Anna", age: 31 }
Output
{ name: 'Anna', age: 31 }

Wer echte Tiefen-Immutabilität im Typsystem will, baut sich einen DeepReadonly<T>-Mapped-Type, der rekursiv über alle Felder geht und überall readonly setzt. Eine Minimalversion sieht so aus:

ts deep-readonly.ts
// Rekursiver Mapped Type — markiert jede Property auf jeder Ebene als readonly.
type DeepReadonly<T> = {
    readonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K];
};

interface Home {
    resident: { name: string; age: number };
}

const home: DeepReadonly<Home> = { resident: { name: "Anna", age: 30 } };

// Jetzt sind BEIDE Ebenen geschuetzt:
// home.resident = { ... };       // Fehler
// home.resident.age++;           // Fehler
// home.resident.name = "Bob";    // Fehler

Bibliotheken wie type-fest liefern einen ausgereiften ReadonlyDeep&lt;T&gt;, der auch Map, Set, Arrays und Tupel sauber behandelt. Im Eigenbau reicht die obige Variante für reine Objekt-Hierarchien — sobald Map, Set oder funktionale Properties mitspielen, lohnt sich der Griff zur Bibliothek.

Optional + Readonly kombiniert

Beide Modifier lassen sich beliebig kombinieren. Die Reihenfolge ist festgelegt: erst readonly, dann der Property-Name mit ?. Diese Kombination — readonly id?: number — taucht in der Praxis am häufigsten bei API-Modellen auf: ein Datensatz, der noch nicht gespeichert wurde, hat keine ID; nach dem POST liefert der Server die ID nach, und ab dann darf sie nicht mehr verändert werden.

ts optional-readonly-combined.ts
// Klassisches API-Pattern: ID wird vom Server vergeben, ist optional auf
// dem Weg hin, aber readonly für alles, was danach passiert.
interface Article {
    readonly id?: number;            // optional vor POST, gesetzt nach POST, danach unveraenderbar
    readonly createdAt?: string;     // gleiches Muster — vom Server gefuellt
    title: string;                   // vom Client editierbar
    body: string;                    // vom Client editierbar
}

// Vor dem Speichern: ID fehlt, das ist legitim.
const draft: Article = {
    title: "Optional und Readonly",
    body: "Lorem ipsum ...",
};

// Nach dem Speichern: Server liefert id und createdAt.
const persisted: Article = {
    id: 42,
    createdAt: "2026-05-17T10:00:00Z",
    title: "Optional und Readonly",
    body: "Lorem ipsum ...",
};

// Lesen — OK.
console.log(persisted.id);

// Schreiben auf id — Compile-Fehler:
// persisted.id = 99;
// Fehler: Cannot assign to 'id' because it is a read-only property.

// Der editierbare Inhalt darf weiterhin geändert werden:
persisted.title = "Optional, Readonly und exactOptionalPropertyTypes";
console.log(persisted.title);
Output
42
Optional, Readonly und exactOptionalPropertyTypes

Das Pattern bringt zwei Garantien gleichzeitig auf den Punkt: die ID ist nicht-pflichtig auf dem Hinweg zum Server und gleichzeitig identitätsbildend, sobald sie da ist — und Identität ist per Definition unveränderlich. Wer eine bestehende Article-ID umschreibt, hat fast immer einen Bug. Der Compiler nimmt dir das ab.

Index Signatures mit optional/readonly

Beide Modifier funktionieren auch in Verbindung mit Index Signatures. Eine readonly-Index-Signature deklariert ein gesamtes Lookup-Objekt als schreibgeschützt; ein optionaler Werte-Typ (number | undefined) signalisiert, dass Lookups fehlen können. Wichtig: der Key einer Index-Signature ist niemals optional in Typsystem-Sinn — er ist ja gerade der dynamische Teil.

ts index-signatures.ts
// Variante 1 — schreibgeschützte Lookup-Tabelle.
interface Translations {
    readonly [key: string]: string;
}

const de: Translations = {
    hello: "Hallo",
    bye: "Tschuess",
};

// de.hello = "Servus";  // Fehler: Index signature in type 'Translations'
//                        // only permits reading.

// Variante 2 — Werte koennen "fehlen" (undefined). Pflicht bei
// noUncheckedIndexedAccess: true, das jeden Lookup als T | undefined typisiert.
interface Counter {
    [key: string]: number | undefined;
}

const counter: Counter = { hits: 3 };
const hits = counter.hits;     // Typ: number | undefined
const miss = counter.unknown;  // Typ: number | undefined — Lookup läuft ins Leere

// Variante 3 — Mischung aus explizitem Property und Index Signature.
// Regel: das explizite Property muss zum Index-Wert-Typ kompatibel sein.
interface Cache {
    readonly version: string;            // explizit, readonly
    readonly [key: string]: string;      // alle weiteren Keys: string, readonly
}
// Wuerde "version: number" stehen, ergaebe das einen Compile-Fehler,
// weil number nicht zum Index-Werte-Typ string passt.

Zwei Detail-Regeln solltest du dir merken. Erstens: explizite Properties müssen zum Werte-Typ der Index-Signature kompatibel sein — andernfalls hätte das Objekt zwei widersprüchliche Aussagen über denselben Schlüssel. Zweitens: wenn du noUncheckedIndexedAccess im tsconfig aktivierst (was ich empfehle), wird jeder Index-Lookup automatisch zu T | undefined, unabhängig davon, ob du | undefined selbst hingeschrieben hast — das ist die ehrlichere Typisierung, denn ein Lookup auf einen unbekannten Schlüssel liefert zur Laufzeit nun mal undefined.

Anti-Patterns

Optional und Readonly sind so simpel, dass die meisten Fehler nicht aus Missverständnis der Syntax kommen, sondern aus gedankenloser Anwendung — die Modifier werden gestreut, ohne dass jemand über die Konsequenzen nachgedacht hätte.

Anti-Pattern 1: Alle Properties zur Sicherheit optional. Wer ein API-Modell defensiv komplett mit ? versieht, „weil man nie weiß", zerstört die Typ-Sicherheit gleich an mehreren Stellen. Jeder Konsument muss jedes Feld einzeln per ?. oder ?? absichern, und der Compiler kann beim Konstruieren des Objekts nicht mehr prüfen, ob Pflichtdaten fehlen.

ts anti-everything-optional.ts
// Anti-Pattern — vermeintlich "sicher", tatsaechlich unbrauchbar.
interface User {
    id?: number;
    name?: string;
    email?: string;
}

function sendInvite(u: User) {
    // Jede einzelne Zeile braucht einen Null-Check, weil "u.email" undefined sein kann.
    if (!u.email) return;
    // ... und so geht das mit jedem Feld weiter.
}

// Loesung: nur das optional machen, was wirklich optional ist.
interface UserFixed {
    id: number;     // jeder gespeicherte User hat eine ID
    name: string;   // jeder User hat einen Namen
    email?: string; // Email darf fehlen — z. B. Test-Accounts
}

Anti-Pattern 2: Readonly, wo Mutation ausdrücklich gewollt ist. readonly ist nicht das Default-Setting — es ist eine bewusste Aussage. Wer ein Form-State-Objekt readonly macht und dann beim Editieren mit Object.assign({}, state, &#123; field: newValue &#125;) herumtrickst, hat sich selbst in den Fuß geschossen. Lass Daten mutierbar, wenn dein Code sie ändern soll — oder nutze as const für echte Konstanten, was sowohl readonly als auch die Literal-Verengung gleichzeitig liefert.

ts anti-readonly-wrong.ts
// Anti-Pattern — readonly an Form-Werten.
interface FormState {
    readonly name: string;
    readonly email: string;
}
// Konsequenz: jedes Input-Event muss ein NEUES Objekt erzeugen,
// selbst wenn dein Code das nicht braucht. Buerokratie ohne Mehrwert.

// Besser: readonly nur dort, wo es semantisch wahr ist (Config, IDs, Konstanten).
// Für echte Konstanten gibt es "as const":
const ROLES = ["admin", "editor", "viewer"] as const;
// ROLES: readonly ["admin", "editor", "viewer"]
// — readonly UND Literal-Typen in einem Schritt.

Anti-Pattern 3: field?: T | undefined parallel. Wer das Fragezeichen UND | undefined an dasselbe Feld schreibt, drückt zweimal dasselbe aus — solange exactOptionalPropertyTypes aus ist. Mit dem Flag an wird daraus eine bewusste Aussage („darf fehlen und darf explizit undefined sein"). Wenn du das Flag nicht aktiviert hast, ist die Doppelung Lärm; aktiv ist sie ein präzises Signal — also entscheide dich, statt beides reflexhaft hinzuschreiben.

Anti-Pattern 4: Optional als Ersatz für Discriminated Unions. Wenn ein Interface vier optional-Felder hat, von denen je nach Zustand zwei gesetzt und zwei leer sind, ist die richtige Modellierung nicht „noch mehr Optional-Properties", sondern eine Discriminated Union mit einem Tag-Feld. Optional ist für ein einzelnes, unabhängig fehlendes Feld — nicht für strukturelle Zustands-Modellierung.

Anti-Pattern 5: readonly als Laufzeit-Schutz interpretieren. readonly ist eine reine Compile-Zeit-Annotation. Wer sicherheitskritisch verhindern muss, dass ein Objekt mutiert wird (z. B. weil es an untrusted Code wandert), nutzt Object.freeze() oder einen Proxy. Der TypeScript-Modifier hilft dem Compiler, deinem eigenen Team und deiner IDE — nicht aber gegen böswilligen oder fehlerhaften Drittcode.

FAQ

Was ist der Unterschied zwischen name?: string und name: string | undefined?

Beide erlauben den Wert undefined — aber nur das Fragezeichen erlaubt, das Property komplett wegzulassen. Bei name: string | undefined ist die Property Pflicht und muss zumindest mit undefined gesetzt werden. Praktisch macht das beim Serialisieren via JSON.stringify einen Unterschied, weil undefined-Werte aus dem Output verschwinden, fehlende Properties hingegen ohnehin nicht erscheinen.

Brauche ich exactOptionalPropertyTypes?

Für neue Projekte: ja. Es macht die Bedeutung des Fragezeichens praezise — Property fehlt vs. Property ist undefined — und verhindert eine ganze Klasse subtiler Bugs an API- und Serialisierungs-Grenzen. In Bestandscode kann das Flag eine groessere Anpassungs-Welle ausloesen; dann lohnt es sich, modulweise vorzugehen.

Schuetzt readonly zur Laufzeit?

Nein. readonly ist eine reine Compile-Zeit-Annotation; nach dem Transpilieren ist sie verschwunden, und das fertige JavaScript erlaubt die Mutation. Wer echten Schutz braucht — etwa weil das Objekt durch Third-Party-Code wandert — nutzt Object.freeze() oder einen Proxy.

Geht readonly tief?

Nein. readonly wirkt nur auf das direkt markierte Property. Ein readonly resident: { name: string } verhindert das Neu-Zuweisen von resident, aber nicht das Aendern von resident.name. Für Tiefen-Immutabilitaet brauchst du einen rekursiven Mapped Type wie DeepReadonly<T> oder eine Library wie type-fest.

Was ist mit Readonly als Utility?

Readonly<T> ist ein eingebauter Mapped Type, der jede direkte Property eines Typs als readonly markiert — flach, nicht tief. Praktisch für "ich habe ein normales Interface und brauche kurzfristig die schreibgeschützte Variante", ohne das Interface selbst zu ändern.

Kann ich Optional und Readonly kombinieren?

Ja. Die Schreibweise ist readonly name?: string — erst der Modifier, dann der Property-Name mit Fragezeichen. Typisch bei Server-vergebenen IDs, die vor dem POST fehlen, danach gesetzt sind und ab dann unveraenderlich.

Wie typisiere ich ein Form-Patch-Objekt mit nur einigen Feldern?

Mit dem Utility-Typ Partial<T>, der jede Property eines Typs optional macht. Aus interface User wird Partial<User>, das genau dann passt, wenn du nur die geänderten Felder übertragen willst. Wer das selbst nachbaut, schreibt Boilerplate ohne Mehrwert.

Was passiert beim Spread mit Optional-Properties?

Wenn ein Optional-Property fehlt, taucht es im Spread-Ergebnis ebenfalls nicht auf. Wenn es als undefined gesetzt ist, wird es als undefined-Property mitkopiert — beides hat unterschiedliche Auswirkungen bei nachfolgenden Defaults via { ...defaults, ...overrides }, weil ein undefined-Override den Default-Wert überschreibt, ein fehlendes Property hingegen nicht.

Wie verhindert man delete obj.key auf readonly?

Genau dafür ist readonly da — der Compiler verbietet auch delete auf einer Readonly-Property mit der Meldung "The operand of a 'delete' operator cannot be a readonly property." Das gilt zusaetzlich zum Schutz gegen direkte Zuweisung. Zur Laufzeit bleibt aber, wie bei der Zuweisung, alles erlaubt — der Schutz wirkt nur für das Type-Checking.

Weiterführende Ressourcen

Externe Quellen

/ Weiter

Zurück zu Interfaces

Zur Übersicht