TypeScript Generics: So erstellen Sie wiederverwendbare Codevorlagen
TypeScript Generics werden genutzt, um wiederverwendbaren und typsicheren Code zu generieren. Das System lässt sich unter anderem auf Funktionen, Klassen, Schnittstellen und Typen anwenden.
Was sind TypeScript Generics?
In beinahe jeder Programmiersprache gibt es Tools, mit denen Nutzerinnen und Nutzer Codevorlagen erstellen können, die sich dann im späteren Verlauf oder bei weiteren Projekten wiederverwenden lassen. Ziel ist es dabei nicht nur, Zeit zu sparen, sondern auch sicheren Code zu erstellen, der sich nahtlos in neue Umgebungen einfügen lässt. Unterschiedliche Komponenten, Funktionen und komplette Datenstrukturen lassen sich auf diese Weise schreiben und replizieren, ohne dass sie dabei ihre Typsicherheit verlieren. In TypeScript werden diese Aufgaben mit Generics durchgeführt. Typen können dadurch als Parameter an andere Typen, Funktionen oder weitere Datenstrukturen weitergegeben werden.
- Vollständige Datensouveränität in deutschen Rechenzentren
- Managed Service ohne Administrationsaufwand
- File-Sharing, Dokumentenbearbeitung & Kommunikation
Syntax und Funktionsweise anhand eines einfachen Beispiels
Die Basis für die Arbeit mit TypeScript Generics sind generische Variablen. Diese funktionieren als eine Art Platzhalter und geben den Datentyp an, der zu einem späteren Zeitpunkt deklariert werden soll. Im Code kennzeichnet man sie mit einem beliebigen Großbuchstaben. Bei der Codeerstellung werden diese Variablen in spitze Klammern eingefasst. Man weist ihnen den tatsächlichen Typnamen zu, sodass anstelle des Platzhalters die gewünschte TypeScript-Funktion, Schnittstelle oder TypeScript-Klasse rückt. Diesen Platzhalter bezeichnet man auch als Type-Parameter. Es ist auch möglich, mehrere dieser Type-Parameter innerhalb einer Klammer zu platzieren. Die Syntax von TypeScript Generics erkennen Sie an diesem einfachen Beispiel:
function Beispielfunktion<T>(parameter1: T): void {
console.log(`Der Datentyp des Parameters ${parameter1} ist: ${typeof parameter1}`)
}
typescriptHierbei nutzen wir den Namen der Funktion („Beispielfunktion“), um die generische Variable „T“ zu definieren. Im folgenden Code deklarieren wir diese Variable als String:
Beispielfunktion<string>("Hier steht ein String.");
typescriptÜbergeben wir nun den Parameterwert string
an die Funktion, erhalten wir die folgende Ausgabe:
Der Datentyp des Parameters Hier steht ein String. ist: string
typescriptTypeScript Generics mit zwei Variablen
Ganz ähnlich funktionieren TypeScript Generics, wenn zwei oder mehr generische Variablen als Platzhalter eingesetzt werden. Im folgenden Beispiel hinterlegen wir die Variablen „T“ und „U“ als Typen für die Parameter „parameter1“ und „parameter2“. Sie werden dabei durch ein Komma voneinander abgetrennt:
function Beispielfunktion<T, U>(parameter1: T, parameter2: U): string {
return JSON.stringify({parameter1, parameter2});
}
typescriptNun weisen wir den beiden Platzhaltern Datentypen und Werte zu. In diesem Fall die Datentypen number
und string
sowie die Werte „11“ und „Spieler“. Dies ist der passende Code:
const str = Beispielfunktion<number, string>(11, "Spieler");
console.log(str);
typescriptBeispiele für reproduzierbare Klassen
Möchten Sie TypeScript Generics anwenden, um reproduzierbare Klassen zu erstellen, ist auch dies möglich. Im folgenden Beispiel nutzen wir Generics, um uns eine Zahl ausgeben zu lassen. Dies ist der passende Code:
class Zahlenwert<T> {
private _value: T | undefined;
constructor(private name: string) {}
public setValue(value: T) {
this._value = value;
}
public getValue(): T | undefined {
return this._value;
}
public toString(): string {
return `${this.name}: ${this._value}`;
}
}
let value = new Zahlenwert<number>('meineZahl');
value.setValue(11);
console.log(value.toString());
typescriptDadurch erhalten Sie die folgende Ausgabe:
meineZahl: 11
typescriptDas Prinzip funktioniert natürlich auch mit anderen Datentypen und mehreren generischen Variablen. Das können Sie im folgenden Beispiel sehen:
class Beispielklasse<T, U> {
vorname: T;
nachname: U;
constructor(vorname: T, nachname: U) {
this.vorname = vorname;
this.nachname = nachname;
}
}
typescriptNun weisen wir den Variablen jeweils den Datentyp String und die vorgesehenen Werte zu:
const person1 = new Beispielklasse<string, string>("Julia", "Schulz");
console.log(`${person1.vorname} ${person1.nachname}`)
typescriptDieses Mal erhalten wir die folgende Ausgabe:
Julia Schulz
typescriptMöchten Sie unterschiedliche Datentypen kombinieren, gehen Sie wie im folgenden Beispiel vor:
class Beispielklasse<T, U> {
zahl: T;
wort: U;
constructor(zahl: T, wort: U) {
this.zahl = zahl;
this.wort = wort;
}
}
typescriptDie Platzhalter bekommen nun die Datentypen number
und string
sowie ihre Werte zugewiesen:
const kombination = new Beispielklasse<number, string>(11, "Spieler");
console.log(`${kombination.zahl} ${kombination.wort}`);
typescriptDies ist die Ausgabe:
11 Spieler
typescriptEinsatz mit Interfaces
Auch für Schnittstellen ist der Einsatz von TypeScript Generics möglich und sogar empfehlenswert. Das Vorgehen ähnelt der Deklarierung einer Klasse:
interface Schnittstelle<T> {
wert: T;
}
typescriptNun implementieren wir die Schnittstelle in die Klasse „Beispielklasse“. Dabei weisen wir der Variablen „T“ den Datentyp string
zu:
class Beispielklasse implements Schnittstelle<string> {
wert: string = "Dies ist ein Beispiel mit einem Interface";
}
const ausgabe = new Beispielklasse();
console.log(ausgabe.wert)
typescriptUnsere Ausgabe sieht dadurch aus wie folgt:
Dies ist ein Beispiel mit einem Interface
typescriptGenerische Arrays erstellen
Für TypeScript Arrays ist der Einsatz der TypeScript Generics ebenfalls möglich. Hier ein einfaches Codebeispiel, bei dem wir die Funktion reverse
nutzen, um die Zahlenreihung eines Arrays umzudrehen:
function reverse<T>(array: T[]): T[] {
return array.reverse();
}
let zahlen: number[] = [10, 7, 6, 13, 9];
let neueReihung: number[] = reverse(zahlen);
console.log(neueReihung);
typescriptWir erhalten dadurch diese Ausgabe:
[9, 13, 6, 7, 10]
typescriptTypeScript Generics für bedingte Typen
Abschließend zeigen wir Ihnen noch, wie Sie mit TypeScript Generics Typen mit einer Bedingung nutzen. Das Resultat ändert sich dabei, je nachdem, ob eine Bedingung erfüllt wird oder nicht. Im folgenden Beispiel soll diese Voraussetzung der Datentyp string
sein. Dies ist der Code:
type IstDiesEinString<T> = T extends string ? true : false;
type A = "beispiel";
type B = {
name: string;
};
type ErstesResultat = IstDiesEinString<A>;
type ZweitesResultat = IstDiesEinString<B>;
typescripttype A
ist also der String „beispiel“, während type B
ein Objekt mit der Eigenschaft „name“ und dem Datentyp string
ist. Diese beiden Typen hinterlegen wir dann als „ErstesResultat“ und „ZweitesResultat“. Überprüfen wir anschließend die beiden Types, werden wir feststellen, dass „ErstesResultat“ als String den Wert true
erhält, während „ZweitesResultat“ false
bleibt.
Deployment direkt via GitHub: Deploy Now von IONOS ist dank automatischer Framework-Erkennung, einem schnellen Setup und optimaler Skalierbarkeit die beste Wahl für Websites und Apps gleichermaßen. Wählen Sie den passenden Tarif für Ihr Projekt!