Conditional Types unter Verwendung des Schlüsselworts infer ermöglichen es, Typen aus komplexen Datentypen zu extrahieren. Ein klassisches Beispiel ist die Extraktion des Typs eines Elements aus einem Array:
type ElementType<T> = T extends (infer U)[] ? U : T;
Hier ermöglicht infer U das Berechnen des Typs des Array-Elements T. Wenn T ein Array ist, wird der Typ seiner Elemente zurückgegeben, andernfalls selbst T.
Wo werden sie verwendet:
Beispiel:
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;
Kann man mehrere infer in einem Conditional Type verwenden? Wie interpretiert TypeScript diesen Fall?
Falsche Antwort:
Richtige Antwort:
type FirstArgument<T> = T extends (infer F, ...any[]) => any ? F : never; // Aber korrekter mit Funktionen: type Args<T> = T extends (...args: infer A) => any ? A : never;
Geschichte
Ein Entwickler schrieb eine Methode zur Ermittlung des Typs des Objekts, das von einer Funktion zurückgegeben wird, übersah jedoch, dass die Funktion ein Promise zurückgeben kann. Das Ergebnis war, dass der Rückgabewert immer Promise<any> war, da kein eingebetteter Conditional mit extract/infer verwendet wurde. Der Code musste in der gesamten Codebasis refakturiert werden.
Geschichte
Im Projekt wurde ein universeller Typ zur Entpackung von verschachtelten Arrays eingeführt, aber der finale else-Zweig in der Bedingung wurde vergessen. TypeScript gab keine Fehlermeldung aus, aber in einigen Fällen war das Ergebnis never, was zu Problemen mit einigen Utility-Typisierungen in externen Bibliotheken führte.
Geschichte
Ein Kollege versuchte, die Typen der Eigenschaften eines großen Interfaces über einen combine-conditional/infer-Typ zu extrahieren, übersah jedoch, dass einige Eigenschaften themselves Union-Typen waren. Infolgedessen gab es unerwartete Kombinationen von Union-Typen als Ausgabe, der Compiler ließ es durchgehen, und die Logik funktionierte nicht korrekt.