ProgrammierungFullstack Entwickler

Beschreiben Sie den Mechanismus der automatisch abgeleiteten Typen (ReturnType, Parameters) in TypeScript. Wofür werden sie verwendet, und welche Besonderheiten gibt es bei der Typisierung komplexer Funktionen (z. B. mit Überladung)?

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort.

ReturnType<T> und Parameters<T> sind Utility-Typen in TypeScript, die es ermöglichen, den Typ des Rückgabewerts einer Funktion automatisch abzuleiten (ReturnType) oder ein Array von Typen ihrer Parameter abzuleiten (Parameters).

Dies ist besonders nützlich, um die Typenkonsistenz zwischen verschiedenen Teilen der Anwendung sicherzustellen und generische Wrapper zu implementieren.

Beispiel für die Verwendung:

function fn(a: number, b: string): boolean { return b.length > a; } type FnReturn = ReturnType<typeof fn>; // boolean type FnParams = Parameters<typeof fn>; // [number, string]

Besonderheiten bei der Überladung von Funktionen: Bei der Überladung von Funktionen bestimmt ReturnType die letzte Signatur der Funktion, während Parameters alle möglichen Überladungen erfasst:

function overloaded(x: number): number; function overloaded(x: string): string; function overloaded(x: any): any { return x; } type OverRet = ReturnType<typeof overloaded>; // any type OverParams = Parameters<typeof overloaded>; // [any]

Das bedeutet, dass die Typisierung von Utility-Typen nicht immer alle Überladungen „sieht“, wodurch die statische Typisierung weniger vorhersagbar wird.

Fangfrage.

Kann man mit ReturnType und Parameters die Typen aller möglichen Überladungen einer benutzerdefinierten Funktion erhalten, indem man jede Überladung einzeln definiert?

Antwort:

Nein. Die Utility-Typen ReturnType und Parameters analysieren nur die „vereinheitlichende“ Signatur der Funktion – wie sie für die Implementierung beschrieben ist. Sie ermöglichen es nicht, die Typen jeder individuellen Überladung zu erhalten – nur die finale implementierte Signatur.

Beispiel:

type P = Parameters<typeof overloaded>; // [any], nicht [number], [string]

Beispiele für reale Fehler aufgrund mangelnder Kenntnisse über die Feinheiten des Themas


Geschichte

Entwickler haben einen Wrapper aroundMethod geschrieben, der ReturnType<T> zur Typisierung des Rückgabewerts verwendet. Dabei wurde die Wrapper-Funktion auf eine überladene Funktion angewendet. Ergebnis: Die Typen waren zu allgemein (any), und der Compiler zeigte bei Fehlern keine Unstimmigkeiten bei den Rückgabewerten an. Ein Bug wurde spät entdeckt, als mit boolean anstelle von string gearbeitet wurde.


Geschichte

In dem Versuch, die Parameter für eine Vielzahl von API-Funktionen über Parameters<T> abzuleiten, berücksichtigte der Entwickler die Überladungen der Methoden nicht. Es trat ein Problem mit „falschen“ Typen auf, bei denen anstelle von [string, number] [any] erwartet wurde. Unit-Tests erfassten diesen Fehler nicht aufgrund der Umsetzung, und echte API-Nutzer erhielten Bugs in der Produktion.


Geschichte

Bei der Migration eines großen Codes von JavaScript nach TypeScript typisierten die Entwickler alles über ReturnType. Später stellte sich heraus, dass die Implementierung stark von der Deklaration der Überladungen abwich. Dadurch führten Szenarien mit fehlerhaften Argumenten zu unerwarteten Runtime-Ausnahmen (z. B. TypeError: x is undefined).