Bedingte Typen in TypeScript

Bedingte Typen in TypeScript bieten eine Möglichkeit, Typen zu erstellen, die von einer Bedingung abhängen. Sie ermöglichen mehr Flexibilität und Ausdruckskraft bei Typdefinitionen und ermöglichen die klare und prägnante Modellierung komplexer Typbeziehungen. Dieser Artikel untersucht, wie bedingte Typen in TypeScript funktionieren, und liefert Beispiele zur Veranschaulichung ihrer Verwendung.

Was sind bedingte Typen?

Bedingte Typen ermöglichen die Erstellung von Typen, die basierend auf einer Bedingung ausgewählt werden. Sie ähneln bedingten Anweisungen in der Programmierung, funktionieren jedoch auf Typebene. Die grundlegende Syntax eines bedingten Typs lautet:

type ConditionalType = T extends U ? X : Y;

In dieser Syntax:

  • T ist der Typ, der überprüft wird.
  • U ist der zu vergleichende Typ.
  • X ist der Typ, der zurückgegeben wird, wenn TU erweitert.
  • Y ist der Typ, der zurückgegeben wird, wenn T nicht U erweitert.

Einfaches Beispiel für bedingte Typen

Dies ist ein einfaches Beispiel für einen bedingten Typ, der unterschiedliche Typen zurückgibt, je nachdem, ob es sich bei einem gegebenen Typ um eine Zeichenfolge handelt oder nicht:

type IsString = T extends string ? "String" : "Not a string";

type Result1 = IsString;  // Result1 is "String"
type Result2 = IsString;  // Result2 is "Not a string"

In diesem Beispiel prüft IsString, ob Tstring erweitert. Wenn dies der Fall ist, ist das Ergebnis "String", andernfalls ist es "Not a string".

Verwenden bedingter Typen mit generischen Typen

Bedingte Typen können auch mit generischen Typen verwendet werden, um flexiblere und wiederverwendbarere Typdefinitionen zu erstellen. Beispielsweise ein Typ, der den Rückgabetyp einer Funktion extrahiert:

type ReturnType = T extends (...args: any[]) => infer R ? R : never;

type FunctionType = (x: number) => string;

type Result = ReturnType;  // Result is string

In diesem Beispiel verwendet ReturnType das Schlüsselwort infer, um den Rückgabetyp R des Funktionstyps T abzuleiten. Wenn T ein Funktionstyp ist, ist ReturnType der Rückgabetyp; andernfalls wird standardmäßig never verwendet.

Bedingte Typen mit Union-Typen

Bedingte Typen können auch mit Union-Typen zusammenarbeiten, um mehrere mögliche Typen zu verarbeiten. Beispielsweise kann zwischen verschiedenen Union-Mitgliedern unterschieden werden:

type ExtractString = T extends string ? T : never;

type UnionType = string | number | boolean;

type Result = ExtractString;  // Result is string

In diesem Beispiel extrahiert ExtractStringstring aus einem Union-Typ UnionType, was zu string führt.

Bedingte Typen mit Typzuordnungen

Bedingte Typen können mit Typzuordnungen kombiniert werden, um komplexere Typtransformationen zu erstellen. Beispielsweise kann die Zuordnung über ein Array von Typen erfolgen, um einen bedingten Typ anzuwenden:

type MapArray = {
  [K in keyof T]: T[K] extends string ? T[K] : never;
};

type ArrayType = [string, number, boolean];

type MappedArray = MapArray;  // MappedArray is [string, never, never]

In diesem Beispiel bildet MapArray jedes Element des Arrays T ab und wendet auf jedes Element einen bedingten Typ an, was zu einem Array führt, in dem nur Zeichenfolgenelemente beibehalten werden.

Abschluss

Bedingte Typen in TypeScript sind ein leistungsstarkes Tool zum Erstellen flexibler und ausdrucksstarker Typdefinitionen. Durch die Nutzung bedingter Typen können Entwickler komplexe Typbeziehungen modellieren, verschiedene Szenarien verarbeiten und die Typsicherheit in ihrem TypeScript-Code verbessern. Das Verständnis der effektiven Verwendung bedingter Typen kann die Fähigkeit zum Schreiben robusten und wartungsfreundlichen TypeScript-Codes erheblich verbessern.