Weniger Code, mehr Nutzen: Pfeilfunktionen und Generics in TypeScript verstehen
Haben Sie jemals ein kleines Dienstprogramm in TypeScript geschrieben, das sowohl mit Zahlen als auch mit Strings und Arrays funktionieren sollte? Und sind dabei auf das Problem gestoßen: Wie macht man den Datentyp flexibel, ohne dass TypeScript Fehler meldet? Die Antwort sind Generics (verallgemeinerte Typen). Und wenn Sie eine prägnante Syntax mögen, verwenden Sie wahrscheinlich Pfeilfunktionen.
Aber hier ist der Haken: Auf Stack Overflow hat die Frage „What is the syntax for Typescript arrow functions with generics?“ Tausende von Aufrufen erhalten. Es stellt sich heraus, dass selbst erfahrene Entwickler manchmal bei dieser scheinbar einfachen Kombination durcheinanderkommen. In diesem Artikel werden wir uns ansehen, wie man TypeScript Arrow Functions mit Generics richtig schreibt, häufige Fehler betrachten und zeigen, wie Sie Ihren Code sauberer und sicherer machen können.
Bereit? Los geht‘s!
Was sind Generics in Pfeilfunktionen?
Zunächst eine kurze Einführung. Generics ermöglichen es, Komponenten (Funktionen, Klassen, Schnittstellen) zu erstellen, die mit verschiedenen Typen arbeiten, nicht nur mit einem bestimmten. Anstatt separate Funktionen für Zahlen und Strings zu schreiben, schreiben Sie eine – mit einem Generic.
Pfeilfunktionen (Arrow Functions) sind eine kompakte Syntax für Funktionen in JavaScript und TypeScript. Wenn Sie sie mit Generics kombinieren, erhalten Sie ein leistungsstarkes Werkzeug zur Erstellung wiederverwendbarer Dienstprogramme.
// Normale Funktion mit Genericfunction identity<T>(arg: T): T { return arg;}
// Pfeilfunktion mit Generic – wie sieht das aus?const arrowIdentity = <T>(arg: T): T => arg;Ganz einfach? Ja, aber es gibt Nuancen, die wir unten besprechen werden.
Grundlegende Syntax: Wie man eine TypeScript Arrow Function mit Generics korrekt deklariert
Der einfachste und gebräuchlichste Weg ist, den Typparameter (Generic) vor den runden Klammern mit den Argumenten anzugeben:
const firstElement = <T>(arr: T[]): T | undefined => { return arr[0];};
// Verwendungconst num = firstElement([1, 2, 3]); // Typ: number | undefinedconst str = firstElement(['a', 'b']); // Typ: string | undefinedHier ist <T> die Deklaration des Generics. TypeScript leitet den Typ T automatisch basierend auf dem übergebenen Argument ab. Wenn Sie den Typ explizit angeben möchten, funktioniert das auch:
const num = firstElement<number>([1, 2, 3]); // Typ explizit angebenWichtig: In JSX (React) kann diese Syntax mit Markup in Konflikt geraten. Für solche Fälle gibt es Workarounds (dazu weiter unten).
Mehrere Generics in einer Pfeilfunktion
Sie können mehrere Typparameter verwenden:
const pair = <T, U>(first: T, second: U): [T, U] => { return [first, second];};
const result = pair(42, 'hello'); // Typ: [number, string]Dies ist besonders nützlich bei der Arbeit mit Dienstprogrammen wie map, reduce oder beim Erstellen von Wrappern.
Probleme mit JSX (React) und deren Lösung
Wenn Sie mit React und TypeScript schreiben, werden Sie feststellen, dass der Compiler die Syntax <T>(arg) als JSX-Tag interpretieren kann. Dies ist ein klassisches Problem, weshalb die Frage auf Stack Overflow so beliebt geworden ist.
Es gibt zwei Hauptlösungen:
1. extends verwenden (auch wenn nicht nötig)
Fügen Sie extends unknown oder extends Record<string, never> hinzu:
const myFunction = <T extends unknown>(arg: T): T => { return arg;};Dies zeigt TypeScript explizit an, dass <T> ein Generic und kein JSX ist.
2. Syntax mit Komma verwenden
In einigen Fällen hilft das Hinzufügen eines Kommas nach dem Generic:
const myFunction = <T,>(arg: T):