Generics in JavaScript: warum sie nützlich sind und wie man sie für Anfänger verwendet

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

Was sind Generics in JavaScript und warum werden sie benötigt?

\n\n

Stellen Sie sich vor, Sie schreiben eine Funktion, die mit verschiedenen Datentypen arbeiten soll – Zahlen, Zeichenketten, Objekten. Ohne Generics müssten Sie entweder Code duplizieren oder any verwenden und dabei die Kontrolle über die Typen verlieren. Generics sind ein Mechanismus, der es ermöglicht, Komponenten (Funktionen, Klassen, Interfaces) zu erstellen, die mit jedem Datentyp arbeiten, aber dennoch die Typinformationen bewahren.

\n\n

Obwohl JavaScript eine dynamisch typisierte Sprache ist, wird im Node.js-Ökosystem häufig TypeScript verwendet, das statische Typisierung hinzufügt. Erst in TypeScript entfalten Generics ihre volle Stärke. Dennoch ist es auch für reines JavaScript nützlich, ihre Prinzipien zu verstehen – besonders wenn Sie Bibliotheken schreiben oder mit modernen Frameworks arbeiten.

\n\n

In diesem Artikel behandeln wir:

\n
    \n
  • Warum Generics benötigt werden
  • \n
  • Wie man Generics in TypeScript deklariert und verwendet
  • \n
  • Beispiele für Node.js (API, Datenverarbeitung)
  • \n
  • Einschränkungen und bewährte Praktiken
  • \n
\n\n

Grundlagen von Generics: Syntax und einfache Beispiele

\n\n

Erstes Generic: die identity-Funktion

\n\n

Ein klassisches Beispiel ist eine Funktion, die das zurückgibt, was sie als Eingabe erhält:

\n\n
// Ohne Generics\nfunction identity(value: any): any {\n  return value;\n}\n\n// Mit Generics\nfunction identity<T>(value: T): T {\n  return value;\n}\n\n// Verwendung\nconst num = identity<number>(42);    // num — number\nconst str = identity<string>('hallo'); // str — string\n
\n\n

Das Symbol <T> ist der Typparameter. Sie können ihn beliebig nennen (T, U, Item), aber traditionell wird T (von Type) verwendet.

\n\n

Generics mit mehreren Parametern

\n\n

Manchmal muss man mit mehreren Typen gleichzeitig arbeiten:

\n\n
function pair<T, U>(first: T, second: U): [T, U] {\n  return [first, second];\n}\n\nconst result = pair<number, string>(1, 'eins');\n// result: [number, string]\n
\n\n

Generics in Pfeilfunktionen (Node.js)

\n\n

In React oder Hilfsfunktionen werden häufig Pfeilfunktionen mit Generics verwendet:

\n\n
const wrapInArray = <T>(item: T): T[] => {\n  return [item];\n};\n\nconst arr = wrapInArray('test'); // arr: string[]\n
\n\n

Anwendung von Generics in realen Node.js-Projekten

\n\n

API-Handler mit typisierten Antworten

\n\n

Stellen Sie sich vor, Sie schreiben eine universelle Funktion für API-Anfragen. Ohne Generics würden Sie die Datentypen verlieren:

\n\n
// Schlecht: any\nasync function fetchData(url: string): Promise<any> {\n  const response = await fetch(url);\n  return response.json();\n}\n\n// Gut: Generics\nasync function fetchData<T>(url: string): Promise<T> {\n  const response = await fetch(url);\n  return response.json();\n}\n\n// Verwendung\ninterface User {\n  id: number;\n  name: string;\n}\n\nconst user = await fetchData<User>('/api/user/1');\nconsole.log(user.name); // TypeScript weiß, dass name ein string ist\n
\n\n

Typisierte Datensammlungen

\n\n

Bei der Arbeit mit Datenbanken (z. B. über Prisma oder Mongoose) helfen Generics, universelle Repositories zu erstellen:

\n\n
class Repository<T extends { id: number }> {\n  private items: T[] = [];\n\n  add(item: T): void {\n    this.items.push(item);\n  }\n\n  getById(id: number): T | undefined {\n    return this.items.find(item => item.id === id);\n  }\n}\n\n// Verwendung\ninterface Product {\n  id: number;\n  title: string;\n  price: number;\n}\n\nconst productRepo = new Repository<Product>();\nproductRepo.add({ id: 1, title: 'Laptop', price: 1000 });\nconst laptop = productRepo.getById(1);\n
\n\n

Wrapper für Fehlerbehandlung

\n\n

Eine universelle Funktion für

Blogs

Buchempfehlungen