Generics in TypeScript: Vollständiger Leitfaden zu Generics

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten
```html

Einführung in Generics in TypeScript



TypeScript ist eine streng typisierte Sprache, die JavaScript um statische Typisierung erweitert. Eine seiner leistungsstärksten und flexibelsten Funktionen ist jedoch der Mechanismus der Generics. Wenn Sie jemals Code geschrieben haben, der mit verschiedenen Datentypen arbeiten soll, dabei aber die Typsicherheit bewahren muss, dann sind Generics genau das Richtige für Sie.



Stellen Sie sich vor, Sie erstellen eine universelle Funktion, die Arrays von Zahlen, Zeichenketten oder Objekten verarbeiten kann. Ohne Generics müssten Sie entweder den Typ any verwenden (was den Nutzen von TypeScript zunichtemacht) oder separate Funktionen für jeden Typ schreiben. Generics lösen dieses Problem elegant und sicher. In diesem Artikel werden wir untersuchen, was Generics sind, warum sie benötigt werden und wie man sie effektiv in realen Projekten einsetzt.



Was sind Generics und warum werden sie benötigt?



Generics sind ein Mechanismus, der es ermöglicht, Komponenten (Funktionen, Klassen, Interfaces) zu erstellen, die mit verschiedenen Datentypen arbeiten können, ohne dabei die Typinformationen zu verlieren. Anstatt einen konkreten Typ festzulegen, verwenden Sie einen Typparameter, der zum Zeitpunkt des Aufrufs eingesetzt wird.



Das Problem ohne Generics



Angenommen, Sie möchten eine Funktion schreiben, die das erste Element eines Arrays zurückgibt. Ohne Generics könnte das so aussehen:



function getFirstElement(arr: any[]): any {  return arr[0];}

const num = getFirstElement([1, 2, 3]); // Typ 'any' — wir haben die Information verlorenconsole.log(num.toUpperCase()); // Fehler zur Laufzeit, aber TypeScript schweigt


Hier verwenden wir any, und TypeScript kann uns nicht warnen, dass num eine Zahl und keine Zeichenkette ist. Dies führt zu potenziellen Fehlern zur Laufzeit.



Die Lösung mit Generics



Schreiben wir nun dieselbe Funktion mit Generics um:



function getFirstElement<T>(arr: T[]): T {  return arr[0];}

const num = getFirstElement([1, 2, 3]); // Typ 'number'const str = getFirstElement(['a', 'b', 'c']); // Typ 'string'

// num.toUpperCase(); // Kompilierungsfehler — TypeScript weiß, dass num eine Zahl ist


Das Symbol <T> ist der Typparameter. Er fungiert als Platzhalter: Wenn wir die Funktion mit einem Zahlenarray aufrufen, wird T zu number, und der Rückgabewert erhält ebenfalls den Typ number. Auf diese Weise bewahren wir die strenge Typisierung, ohne an Flexibilität zu verlieren.



Wie man Generics verwendet: grundlegende Szenarien



Generics werden nicht nur in Funktionen, sondern auch in Klassen, Interfaces und Typen eingesetzt. Betrachten wir die häufigsten Szenarien.



Generics in Funktionen



Der einfachste und häufigste Fall sind Funktionen, die mit Daten verschiedener Typen arbeiten. Zum Beispiel eine Funktion zum Erstellen eines Schlüssel-Wert-Paares:



function createPair<K, V>(key: K, value: V): { key: K; value: V } {  return { key, value };}

const pair = createPair('id', 123); // { key: string; value: number }console.log(pair.key.toUpperCase()); // Funktioniert// pair.key.toFixed(); // Fehler — key ist ein string


Hier verwenden wir zwei Typparameter: K für den Schlüssel und V für den Wert. TypeScript leitet die Typen automatisch aus den Argumenten ab.



Generics in Klassen



Generics eignen sich hervorragend für die Erstellung universeller Klassen wie Stapel (Stacks), Warteschlangen (Queues) oder Datenspeicher:



class Stack<T> {  private items: T[] = [];

push(item: T): void { this.items.push(item); }

pop(): T | undefined { return this.items.pop(); }

peek(): T | undefined { return this.items[this.items.length - 1]; }}

const numberStack = new Stack<number>();numberStack.push(10);numberStack.push(20);console.log(numberStack ```

Blogs

Buchempfehlungen