Fortgeschritten
Union und Intersection Types in TypeScript
Verstehe, wie du in TypeScript mehrere Typen mit Union und Intersection kombinierst und damit flexible, praezise Typdefinitionen erstellst.
Inhalt
Union und Intersection Types in TypeScript
TypeScript bietet zwei grundlegende Wege, Typen miteinander zu kombinieren: Union Types und Intersection Types. Beide sind unverzichtbar fuer praxisnahes Typisieren, haben aber sehr unterschiedliche Semantik. Dieser Ratgeber erklaert beide Konzepte mit konkreten Beispielen und zeigt, wann welches Werkzeug geeignet ist.
Union Types: Ein Typ von vielen
Ein Union Type beschreibt einen Wert, der einem von mehreren Typen entsprechen kann. Die Schreibweise verwendet den senkrechten Strich:
type StatusCode = 200 | 400 | 404 | 500;
type Eingabe = string | number | boolean;
function verarbeite(wert: string | number): string {
if (typeof wert === "string") {
return wert.toUpperCase();
}
return wert.toFixed(2);
}
TypeScript kennt den genauen Typ innerhalb einer Bedingung und erzwingt die korrekte Behandlung. Diesen Mechanismus nennt man Type Narrowing.
Literal Types in Union
Besonders nuetzlich sind Union Types in Kombination mit Literal Types:
type Richtung = "oben" | "unten" | "links" | "rechts";
type Antwort = "ja" | "nein" | "vielleicht";
function bewegeCharakter(richtung: Richtung): void {
console.log("Bewege nach:", richtung);
}
bewegeCharakter("oben"); // OK
// bewegeCharakter("diagonal"); // Fehler
Literal Unions machen Funktionssignaturen selbstdokumentierend und verhindern ungueltige Eingaben ohne zusaetzliche Laufzeitpruefungen.
Discriminated Unions: Varianten sicher modellieren
Discriminated Unions (auch Tagged Unions) sind ein kraftvolles Muster fuer das Modellieren von Zustaenden oder Varianten. Jede Variante traegt ein gemeinsames Literalfeld, den Diskriminator:
interface LaedeZustand {
status: "laedt";
}
interface ErfolgZustand {
status: "erfolg";
daten: string[];
}
interface FehlerZustand {
status: "fehler";
meldung: string;
}
type LadenStatus = LaedeZustand | ErfolgZustand | FehlerZustand;
function renderStatus(zustand: LadenStatus): string {
switch (zustand.status) {
case "laedt":
return "Wird geladen...";
case "erfolg":
return zustand.daten.join(", ");
case "fehler":
return "Fehler: " + zustand.meldung;
}
}
TypeScript prueft in jedem case-Zweig, welche Felder verfuegbar sind. Fehlt ein Fall, warnt der Compiler.
Exhaustiveness Checking
Um sicherzustellen, dass alle Varianten behandelt werden, kann man einen never-Trick verwenden:
function nichtErreichbar(wert: never): never {
throw new Error("Unbehandelter Fall: " + String(wert));
}
function renderStatusSicher(zustand: LadenStatus): string {
switch (zustand.status) {
case "laedt":
return "Wird geladen...";
case "erfolg":
return zustand.daten.join(", ");
case "fehler":
return "Fehler: " + zustand.meldung;
default:
return nichtErreichbar(zustand);
}
}
Wenn eine neue Variante zu LadenStatus hinzugefuegt wird, erzwingt der Compiler eine entsprechende Behandlung im Switch.
Intersection Types: Alle Typen gleichzeitig
Waehrend Union Types “oder” bedeuten, bedeuten Intersection Types “und”. Ein Wert muss alle kombinierten Typen gleichzeitig erfuellen:
interface HatName {
name: string;
}
interface HatAlter {
alter: number;
}
type Person = HatName & HatAlter;
const person: Person = {
name: "Luisa",
alter: 28,
};
Der Intersection-Typ Person erfordert sowohl name als auch alter. Fehlt eines der Felder, meldet der Compiler einen Fehler.
Intersection fuer Mixins und Erweiterungen
Intersection Types eignen sich gut, um bestehende Typen um zusaetzliche Eigenschaften zu erweitern, ohne Vererbung zu verwenden:
interface Basisentitaet {
id: number;
erstelltAm: string;
}
interface Produkt {
bezeichnung: string;
preis: number;
}
type ProduktMitMeta = Produkt & Basisentitaet;
const artikel: ProduktMitMeta = {
id: 1,
erstelltAm: "2026-05-15",
bezeichnung: "TypeScript Kurs",
preis: 49.99,
};
Im Playground laesst sich gut beobachten, wie TypeScript bei fehlenden Feldern im Intersection-Typ sofort einen Hinweis gibt.
Konflikte in Intersection Types
Was passiert, wenn beide Typen dasselbe Feld mit unterschiedlichen Typen definieren?
type A = { wert: string };
type B = { wert: number };
type AB = A & B;
// Der Typ von 'wert' waere: string & number = never
Das Feld wert haette den Typ never, da kein Wert gleichzeitig string und number sein kann. TypeScript erlaubt die Typdefinition, aber jede Nutzung von wert fuehrt zu einem Fehler. Dieses Verhalten ist ein Hinweis, dass die Typmodellierung ueberdacht werden sollte.
Union vs. Intersection: Die richtige Wahl
Die Entscheidung haengt vom Modell ab:
// Union: Ein Wert ist entweder Admin oder Gast
type Nutzer = Admin | Gast;
// Intersection: Ein Wert hat sowohl Administrator- als auch Protokoll-Eigenschaften
type AdminMitProtokoll = Administrator & Protokollierbar;
Union Types eignen sich fuer Varianten und Alternativen. Intersection Types eignen sich fuer Kombinationen und Erweiterungen.
Praktisches Beispiel: API-Antwort modellieren
Ein realistisches Szenario kombiniert beide Konzepte:
interface Basisantwort {
statusCode: number;
zeitstempel: string;
}
interface ErfolgsAntwort {
typ: "erfolg";
daten: unknown;
}
interface FehlerAntwort {
typ: "fehler";
fehlerCode: string;
meldung: string;
}
type ApiAntwort = (ErfolgsAntwort | FehlerAntwort) & Basisantwort;
Jede ApiAntwort hat immer statusCode und zeitstempel aus dem Intersection-Teil, und ist zusaetzlich entweder eine Erfolgs- oder eine Fehlerantwort.
Zusammenfassung
Union und Intersection Types sind fundamentale Bausteine fuer ausdrucksstarke TypeScript-Definitionen. Union Types modellieren Alternativen, Intersection Types kombinieren Eigenschaften. Discriminated Unions mit Exhaustiveness Checking machen zustandsbasierte Logik sicher und erweiterbar. Mit diesen Werkzeugen laesst sich reales Domainwissen praezise in Typen abbilden.
Häufige Fragen
Was ist der Unterschied zwischen Union und Intersection?
Ein Union-Typ akzeptiert Werte, die einem von mehreren Typen entsprechen. Ein Intersection-Typ erfordert, dass ein Wert alle kombinierten Typen gleichzeitig erfuellt. Union ist 'oder', Intersection ist 'und'.
Wann verwende ich Discriminated Unions?
Discriminated Unions sind ideal, wenn du eine endliche Menge von Varianten modellieren willst, zum Beispiel Zustaende einer Anfrage (laden, erfolgreich, fehlgeschlagen) oder Arten von Ereignissen in einem Event-System.
Kann man Union und Intersection mischen?
Ja, TypeScript erlaubt beliebige Kombinationen. Die Praezedenz ist dabei zu beachten: Intersection bindet staerker als Union. Im Zweifelsfall helfen Klammern, die Absicht klarzumachen.
Quellen
Über die Autorenschaft
Jan-Tristan Rudat
Redakteur typescript-playground.de
Themengebiet: Generationen, Kulturgeschichte, Sternzeichen, Pop-Phänomene rund ums Alter
Mehr über Jan-Tristan Rudat →Verwandte Artikel
Grundlagen
Was ist TypeScript? Eine Einführung in die typisierte JavaScript-Erweiterung
TypeScript erweitert JavaScript um statische Typen und macht große Codebases wartbarer. Lerne die Grundlagen, die Geschichte und die wichtigsten Vorteile von TypeScript.
Lesezeit 7 Min.
Grundlagen
TypeScript vs. JavaScript: Die wichtigsten Unterschiede im Überblick
TypeScript und JavaScript unterscheiden sich grundlegend in der Typprüfung, Werkzeugunterstützung und Wartbarkeit. Dieser Ratgeber erklärt die Unterschiede und hilft bei der Wahl der richtigen Sprache.
Lesezeit 8 Min.
Typen
TypeScript Typen Grundlagen: string, number, boolean und mehr
Die primitiven Typen string, number und boolean sind das Fundament von TypeScript. Dieser Ratgeber erklärt alle grundlegenden Typen mit praktischen Beispielen.
Lesezeit 9 Min.