Das Verständnis des infer Schlüsselworts in TypeScript
Daniel Hayes
Full-Stack Engineer · Leapcell

Das Schlüsselwort infer
in TypeScript wird in bedingten Typen verwendet, um einen Typ zu inferieren (herzuleiten). Dies ist besonders nützlich beim Umgang mit komplexen Typen, da es uns ermöglicht, Typen zu extrahieren oder zu transformieren.
Grundlegende Verwendung
Das Schlüsselwort infer
kann nur innerhalb bedingter Typen verwendet werden, typischerweise in Verbindung mit Generics und dem Schlüsselwort extends
. Die Syntax lautet wie folgt:
type Moment<T> = T extends infer U ? U : never;
Hier bedeutet T extends infer U
, dass wir versuchen, den Typ T
herzuleiten und ihn U
zuzuweisen. Wenn die Typinferenz erfolgreich ist, wird U
zum inferierten Typ.
Wir können es verwenden, um verschiedene Typen abzuleiten. Hier sind ein paar Beispiele:
type Moment<T> = T extends infer U ? U : never; type StringType = Moment<string>; // string type NumberType = Moment<number>; // number type UnionType = Moment<string | number>; // string | number interface User { name: string; age: number; } type UserType = Moment<User>; // User
In diesen Beispielen gibt Moment<T>
im Wesentlichen nur den Typ T
ohne Konvertierung oder Verarbeitung zurück. Dies dient hauptsächlich dazu, die grundlegende Verwendung von bedingten Typen und Typinferenz zu demonstrieren.
Häufige Beispiele
Extrahieren des Rückgabetyps einer Funktion
Angenommen, wir haben einen Funktionstyp und möchten seinen Rückgabetyp extrahieren. Wir können dies tun:
type GetReturnType<T> = T extends (...args: any[]) => infer R ? R : never; type ExampleFunction = (x: number, y: string) => boolean; type ReturnTypeOfExampleFunction = GetReturnType<ExampleFunction>; // boolean
Im obigen Code:
T extends (...args: any[]) => infer R
: Dies prüft, obT
ein Funktionstyp ist.(...args: any[])
bedeutet, dass die Funktion eine beliebige Anzahl von Argumenten akzeptieren kann.infer R
: WennT
ein Funktionstyp ist, dann leitetinfer R
den Rückgabetyp der Funktion ab und weist ihn der TypvariablenR
zu.? R : never
: WennT
ein Funktionstyp ist, wird der inferierte RückgabetypR
zurückgegeben; andernfalls wirdnever
zurückgegeben.
Extrahieren des Elementtyps eines Arrays
Wir können infer
auch verwenden, um den Elementtyp eines Arrays zu extrahieren:
type GetArrayElementType<T> = T extends (infer U)[] ? U : never; type Moment = string[]; type Example1Array = Array<string>; type ElementTypeOfExampleArray = GetArrayElementType<Moment>; // string type ElementTypeOfExample1Array = GetArrayElementType<Example1Array>; // string
Hier verwenden wir T extends (infer U)[]
, um den Elementtyp U
des Arrays abzuleiten. Da T
string[]
ist, wird U
zu string
.
string[] extends (infer U)[ ]
Es ist wichtig zu beachten, dass infer
-Deklarationen nur innerhalb der extends
-Klausel von bedingten Typen zulässig sind und die mit infer
deklarierte Typvariable nur innerhalb des True-Zweigs verfügbar ist.
Erweiterte Beispiele
Extrahieren des Werttyps eines Promise
Wenn wir einen Promise
-Typ haben, können wir seinen aufgelösten Werttyp extrahieren:
type GetPromiseValueType<T> = T extends Promise<infer U> ? U : never; // Beispiel type ExamplePromise = Promise<number>; type ValueTypeOfExamplePromise = GetPromiseValueType<ExamplePromise>; // number
Im obigen Code:
T extends Promise<infer U>
: Dies prüft, obT
einPromise
-Typ ist.infer U
: WennT
einPromise
-Typ ist, leitetinfer U
den aufgelösten Werttyp desPromise
ab und weist ihnU
zu.? U : never
: WennT
einPromise
-Typ ist, wird der inferierte WerttypU
zurückgegeben; andernfalls wirdnever
zurückgegeben.
Extrahieren der Parametertypen einer Funktion
Manchmal müssen wir die Parametertypen einer Funktion erhalten. Wir können infer
verwenden, um dies zu erreichen:
type GetParameters<T> = T extends (...args: infer P) => any ? P : never; type ExampleFunction = (a: number, b: string) => void; type Params = GetParameters<ExampleFunction>; // [number, string]
Im obigen Code:
T extends (...args: infer P) => any
: Dies prüft, obT
ein Funktionstyp ist.infer P
: WennT
ein Funktionstyp ist, leitetinfer P
die Parametertypen der Funktion ab und weist sieP
zu.? P : never
: WennT
ein Funktionstyp ist, werden die inferierten ParametertypenP
zurückgegeben; andernfalls wirdnever
zurückgegeben.
Extrahieren von Konstruktor-Parametertypen
Wir können infer
auch verwenden, um die Parametertypen eines Klassenkonstruktors zu extrahieren:
type ConstructorParameters<T> = T extends new (...args: infer P) => any ? P : never; class ExampleClass { constructor(public a: number, public b: string) {} } type Params = ConstructorParameters<typeof ExampleClass>; // [number, string]
Komplexe Inferenz in bedingten Typen
Angenommen, wir müssen komplexe Inferenzlogik innerhalb eines bedingten Typs verwenden:
type IsArray<T> = T extends (infer U)[] ? U : never; type IsFunction<T> = T extends (...args: any[]) => infer R ? R : never; type ExtractType<T> = T extends any[] ? IsArray<T> : T extends (...args: any[]) => any ? IsFunction<T> : T; // Beispiel type ArrayType = ExtractType<string[]>; // string type FunctionReturnType = ExtractType<() => number>; // number type DefaultType = ExtractType<boolean>; // boolean
In diesem Code:
type ExtractType<T> = T extends any[] ? IsArray<T> : T extends (...args: any[]) => any ? IsFunction<T> : T;
T extends any[] ? IsArray<T>
: WennT
ein Array-Typ ist, gibIsArray
zurück, das den Elementtyp des Arrays extrahiert.T extends (...args: any[]) => any ? IsFunction<T>
: WennT
ein Funktionstyp ist, gibIsFunction
zurück, das den Rückgabetyp der Funktion extrahiert.T
: WennT
weder ein Array-Typ noch ein Funktionstyp ist, gibT
selbst zurück.
Zusammenfassung
Das Schlüsselwort infer
wird in bedingten Typen verwendet, um eine neue Typvariable von einem anderen Typ abzuleiten. Es ermöglicht das Extrahieren und Verwenden spezifischer Subtypen oder Eigenschaften während der Typüberprüfung, wodurch die Ausdruckskraft und Flexibilität des TypeScript-Typsystems verbessert werden. Einfach ausgedrückt hilft infer
dabei, die gewünschten Teile automatisch aus komplexen Typen zu extrahieren.
Wir sind Leapcell, Ihre erste Wahl für das Hosten von Node.js-Projekten.
Leapcell ist die Serverless-Plattform der nächsten Generation für Webhosting, asynchrone Aufgaben und Redis:
Mehrsprachige Unterstützung
- Entwickeln Sie mit Node.js, Python, Go oder Rust.
Stellen Sie unbegrenzt Projekte kostenlos bereit
- Zahlen Sie nur für die Nutzung – keine Anfragen, keine Gebühren.
Unschlagbare Kosteneffizienz
- Pay-as-you-go ohne Leerlaufgebühren.
- Beispiel: 25 $ unterstützen 6,94 Millionen Anfragen bei einer durchschnittlichen Antwortzeit von 60 ms.
Optimierte Entwicklererfahrung
- Intuitive Benutzeroberfläche für mühelose Einrichtung.
- Vollständig automatisierte CI/CD-Pipelines und GitOps-Integration.
- Echtzeitmetriken und Protokollierung für umsetzbare Erkenntnisse.
Mühelose Skalierbarkeit und hohe Leistung
- Automatische Skalierung zur einfachen Bewältigung hoher Parallelität.
- Kein betrieblicher Overhead – konzentrieren Sie sich einfach auf den Aufbau.
Erfahren Sie mehr in der Dokumentation!
Folgen Sie uns auf X: @LeapcellHQ