Fortgeschritten

Generics in TypeScript: Wiederverwendbare Typen verstehen

Lerne, wie generische Typen in TypeScript funktionieren, wann du sie einsetzt und wie du damit flexiblen, typsicheren Code schreibst.

Lesezeit 7 Min. Aktualisiert 20.05.2026 1 Quellen Mateusz Viola Mateusz Viola
Inhalt

Generics in TypeScript: Wiederverwendbare Typen verstehen

Generics sind eines der maechtigsten Werkzeuge in TypeScript. Sie erlauben es, Funktionen, Klassen und Interfaces zu schreiben, die mit verschiedenen Datentypen arbeiten, ohne die Typsicherheit zu verlieren. Wer dieses Konzept einmal verstanden hat, schreibt deutlich weniger Duplikat-Code und gleichzeitig robustere Anwendungen.

Was sind Generics?

Ein Generic ist ein Platzhalter fuer einen Typ, der erst beim Aufruf der Funktion oder beim Erstellen einer Klasse festgelegt wird. Du kannst dir Generics wie Parameter vorstellen, aber fuer Typen statt fuer Werte.

Ohne Generics muesste man fuer jede Kombination aus Funktion und Datentyp eine eigene Implementierung schreiben. Mit Generics schreibst du einmal und verwendest es beliebig oft.

Die Grundsyntax

Ein Generic wird in spitzen Klammern angegeben. Traditionell nimmt man den Buchstaben T als Namen, aber jeder gueltiger Bezeichner funktioniert:

function identitaet<T>(wert: T): T {
  return wert;
}

const zahl = identitaet<number>(42);
const text = identitaet<string>("Hallo");

TypeScript kann den Typparameter in vielen Faellen auch selbst ableiten:

const zahl = identitaet(42);        // TypeScript leitet T = number ab
const text = identitaet("Hallo");   // TypeScript leitet T = string ab

Du kannst das Playground verwenden, um diese Typinferenz direkt im Browser auszuprobieren und die abgeleiteten Typen zu beobachten.

Generische Arrays und Rueckgabetypen

Ein haeufiger Anwendungsfall sind Funktionen, die mit Arrays arbeiten:

function erstesElement<T>(arr: T[]): T | undefined {
  return arr[0];
}

const namen = ["Anna", "Bert", "Clara"];
const erster = erstesElement(namen); // Typ: string | undefined

const zahlen = [10, 20, 30];
const erstZahl = erstesElement(zahlen); // Typ: number | undefined

Constraints: Generics einschraenken

Manchmal soll ein Generic nicht jeden beliebigen Typ akzeptieren, sondern nur solche, die bestimmte Eigenschaften haben. Das erreicht man mit dem Schluesselwort extends:

interface HatLaenge {
  length: number;
}

function laengePlusEins<T extends HatLaenge>(wert: T): number {
  return wert.length + 1;
}

laengePlusEins("Hallo");    // 6
laengePlusEins([1, 2, 3]);  // 4
// laengePlusEins(42);      // Fehler: number hat keine length-Eigenschaft

Durch T extends HatLaenge stellt TypeScript sicher, dass nur Typen mit einer length-Eigenschaft uebergeben werden. Das ist praeziser als any und sicherer als ein allgemeines T.

Mehrere Typparameter

Du kannst mehrere Typparameter kombinieren. Ein klassisches Beispiel ist eine Funktion, die zwei Werte zu einem Paar zusammenfasst:

function paaren<K, V>(schluessel: K, wert: V): [K, V] {
  return [schluessel, wert];
}

const eintrag = paaren("id", 123);
// Typ: [string, number]

const flagge = paaren("aktiv", true);
// Typ: [string, boolean]

Generische Interfaces und Klassen

Generics sind nicht nur auf Funktionen beschraenkt. Auch Interfaces und Klassen koennen Typparameter haben:

interface Behaelter<T> {
  inhalt: T;
  leer(): boolean;
}

class Box<T> implements Behaelter<T> {
  constructor(public inhalt: T) {}

  leer(): boolean {
    return false;
  }
}

const zahlenBox = new Box<number>(42);
const textBox = new Box<string>("TypeScript");

Generische Klassen sind die Grundlage fuer Datenstrukturen wie Listen, Stacks oder Queues, bei denen der Typ des gespeicherten Elements offen gelassen werden soll.

Default-Typen bei Generics

Seit TypeScript 2.3 koennen Generics einen Standardtyp haben, der verwendet wird, wenn kein expliziter Typ angegeben wird:

interface Antwort<T = string> {
  daten: T;
  statusCode: number;
}

const textAntwort: Antwort = {
  daten: "OK",
  statusCode: 200,
};

const zahlenAntwort: Antwort<number> = {
  daten: 404,
  statusCode: 404,
};

Das macht APIs einfacher zu verwenden, wenn ein sinnvoller Standardtyp existiert.

keyof und Lookup-Typen in Generics

Eine besonders nuetzliche Kombination ist keyof zusammen mit Generics. So kannst du Funktionen schreiben, die nur auf vorhandene Eigenschaften eines Objekts zugreifen duerfen:

function eigenschaft<T, K extends keyof T>(obj: T, schluessel: K): T[K] {
  return obj[schluessel];
}

const person = { name: "Maria", alter: 30 };
const name = eigenschaft(person, "name");   // Typ: string
const alter = eigenschaft(person, "alter"); // Typ: number
// eigenschaft(person, "adresse");          // Fehler: 'adresse' existiert nicht

Diese Technik verhindert Tippfehler bei Eigenschaftsnamen zur Kompilierzeit.

Utility-Typen als Generics

TypeScript bringt viele eingebaute Utility-Typen mit, die intern alle auf Generics basieren. Dazu gehoeren Partial, Required, Readonly, Pick und Omit:

interface Nutzer {
  id: number;
  name: string;
  email: string;
}

// Alle Eigenschaften optional machen
type TeilNutzer = Partial<Nutzer>;

// Nur bestimmte Felder auswaehlen
type NutzerKopf = Pick<Nutzer, "id" | "name">;

// Ein Feld entfernen
type OhneEmail = Omit<Nutzer, "email">;

Das Verstehen dieser Utility-Typen setzt grundlegendes Verstaendnis von Generics voraus und ist ein wichtiger Schritt auf dem Weg zum fortgeschrittenen TypeScript-Entwickler.

Tipps fuer den Alltag

Verwende aussagekraeftige Namen fuer Typparameter, wenn der Kontext komplex wird. Statt T macht TElement, TSchluessel oder TWert den Code lesbarer. Kurze Namen wie T und U sind in Ordnung fuer einfache Hilfsfunktionen, werden aber schnell unuebersichtlich.

Probiere Generics aktiv im Playground aus. Dort siehst du sofort, wie TypeScript die Typen ableitet und wo Einschraenkungen greifen. Das beschleunigt das Lernen erheblich.

Generics sind kein optionales Extra, sondern das Fundament vieler TypeScript-Bibliotheken. Wer sie beherrscht, kann mit Frameworks wie React, Angular oder NestJS deutlich effizienter arbeiten und eigene, robuste Abstraktionen bauen.

Häufige Fragen

Wann sollte ich Generics verwenden?

Immer dann, wenn eine Funktion oder Klasse mit verschiedenen Datentypen arbeiten soll, ohne dabei die Typsicherheit aufzugeben. Klassische Beispiele sind Hilfsfunktionen, Collections und API-Wrapper.

Was ist der Unterschied zwischen einem Generic und dem Typ 'any'?

Mit 'any' verlierst du alle Typinformationen und TypeScript kann keine Fehler mehr erkennen. Ein Generic behält die Typinformation und gibt sie weiter, sodass TypeScript Fehler zur Kompilierzeit finden kann.

Kann ich mehrere Typparameter in einem Generic verwenden?

Ja, du kannst beliebig viele Typparameter angeben, zum Beispiel in einer Funktion, die zwei verschiedene Typen kombiniert. Die Namen T, U, K, V sind Konvention, aber frei waehlbar.

Quellen

Mateusz Viola

Über die Autorenschaft

Mateusz Viola

Betreiber und redaktionelle Verantwortung typescript-playground.de

Themengebiet: Mathematik, Kalenderrechnung, Schaltjahre, Statistik und ISO 8601

Mehr über Mateusz Viola →

Verwandte Artikel

TypeScript Playground nutzen

Sofort im Browser, ohne Anmeldung.

Zum Playground