Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

Conditional Types in TypeScript

Conditional Types

~15 Min. Lesezeit Zuletzt aktualisiert am 8. August 2026

Das letzte große Werkzeug für ECHTE Typ-Logik: Conditional Types – "Wenn-Dann"-Entscheidungen, aber auf TYP-Ebene statt auf Werte-Ebene, ausgewertet zur Kompilierzeit.

Die Grundsyntax

type IstString<T> = T extends string ? true : false;

type A = IstString<'hallo'>; // true
type B = IstString<42>;      // false

T extends string ? true : false liest sich fast wie der normale JavaScript-Ternäroperator (bedingung ? dann : sonst) – extends prüft hier NICHT Vererbung (wie bei Klassen, Kapitel 13), sondern "ist T ZUWEISBAR zu string?", ausgewertet auf TYP-Ebene.

Praxis: den Rückgabetyp einer Methode extrahieren

Wir bauen einen Conditional Type, der aus JEDER Repository<T>-Klasse (Kapitel 17-18) automatisch den ELEMENT-Typ extrahiert – nützlich, wenn man den Typ NUR aus der Repository-Klasse kennt, ohne ihn ein zweites Mal manuell hinzuschreiben:

src/types/ExtrahiereElementTyp.ts
import { Repository } from '../repository/Repository.js';

export type ExtrahiereElementTyp<R> = R extends Repository<infer T> ? T : never;

// Angewendet:
type BuchRepo = Repository<import('../models/Buch.js').Buch>;
type ExtrahierterTyp = ExtrahiereElementTyp<BuchRepo>; // Buch

infer T ist der SCHLÜSSEL zu Conditional Types: es sagt TypeScript "finde HERAUS, welcher konkrete Typ hier an dieser Position steht, und nenne ihn T" – infer kann NUR innerhalb der extends-Bedingung eines Conditional Type verwendet werden, nirgendwo sonst.

Verteilte Conditional Types bei Unions

type OhneArray<T> = T extends any[] ? never : T;

type Gemischt = string | number[] | boolean;
type Gefiltert = OhneArray<Gemischt>; // string | boolean - number[] wurde entfernt!

Ein SUBTILES, aber wichtiges Detail: wird ein Conditional Type auf eine UNION angewendet, wird er AUTOMATISCH auf JEDES Mitglied der Union EINZELN angewendet und die Ergebnisse wieder zu einer Union zusammengeführt ("Distributive Conditional Types") – never aus Kapitel 4/19 verschwindet dabei aus der resultierenden Union, da string | never zu string vereinfacht wird.

Verteilung verhindern mit eckigen Klammern

type OhneArrayNichtVerteilt<T> = [T] extends [any[]] ? never : T;

type Ergebnis = OhneArrayNichtVerteilt<Gemischt>; // never - GESAMTE Union geprüft, nicht Mitglied für Mitglied

[T] (T in eckige Klammern eingepackt) VERHINDERT die automatische Verteilung – manchmal gewünscht, wenn man die GESAMTE Union als EINEN Typ prüfen will, statt Mitglied-für-Mitglied. Ein fortgeschrittenes Detail, das selten gebraucht wird, aber überraschendes Verhalten erklärt, falls es einmal auftritt.

Eingebaute Beispiele: Awaited und NonNullable

type A = Awaited<Promise<string>>; // string - "packt" ein Promise aus
type B = NonNullable<string | null | undefined>; // string - entfernt null/undefined

Awaited und NonNullable aus Kapitel 20 sind SELBST als Conditional Types mit infer implementiert – jetzt verstehen Sie GENAU, wie sie intern funktionieren, nicht nur, wie man sie benutzt.

Tipp: Faustregel: Conditional Types SELBST schreiben ist FORTGESCHRITTEN und selten im alltäglichen Anwendungscode nötig – meist reicht ein bereits eingebauter Utility Type (Kapitel 20). Nützlich vor allem beim Schreiben WIEDERVERWENDBARER Bibliotheks-Typen, die sich an BELIEBIGE Eingabetypen anpassen sollen – GENAU wie wir es hier mit ExtrahiereElementTyp demonstriert haben.