Typen
Interfaces und Types in TypeScript: Unterschiede und Einsatzgebiete
interface und type alias sind zwei Wege, um Objektstrukturen in TypeScript zu beschreiben. Dieser Ratgeber erklärt die Unterschiede und wann welche Option die bessere Wahl ist.
Inhalt
Interfaces und Types in TypeScript
TypeScript bietet zwei Hauptwege, um Strukturen zu beschreiben: das Schlüsselwort interface und Type Aliases mit dem Schlüsselwort type. Auf den ersten Blick scheinen sie austauschbar zu sein, es gibt aber wichtige Unterschiede, die im Alltag relevant werden.
Was ist ein Interface?
Ein Interface definiert die Form eines Objekts. Es legt fest, welche Felder ein Objekt haben muss, welche Typen diese Felder haben und ob sie optional sind.
interface Kunde {
id: number;
name: string;
email: string;
telefon?: string; // Optional: Fragezeichen macht das Feld nicht zwingend erforderlich
}
const neuerKunde: Kunde = {
id: 1,
name: "Anna Bauer",
email: "anna@beispiel.de",
// telefon ist optional, muss also nicht angegeben werden
};
Das Fragezeichen nach dem Feldnamen markiert optionale Eigenschaften. Felder ohne Fragezeichen sind zwingend erforderlich.
Was ist ein Type Alias?
Ein Type Alias weist einem Typ einen Namen zu. Das ist bei Objektstrukturen ähnlich wie bei Interfaces, aber Type Aliases sind vielseitiger:
type Kunde = {
id: number;
name: string;
email: string;
telefon?: string;
};
// Aber auch für primitive Typen möglich:
type KundenId = number;
type Status = "aktiv" | "inaktiv" | "gesperrt";
// Und für Tupel:
type Koordinaten = [number, number];
Ein Interface kann dagegen nur Objektstrukturen beschreiben. Diese Vielseitigkeit ist ein wichtiger Vorteil von Type Aliases.
Vererbung und Erweiterung
Beide Ansätze unterstützen Vererbung, aber auf unterschiedliche Weise.
Bei Interfaces nutzt man extends:
interface Person {
vorname: string;
nachname: string;
}
interface Mitarbeiter extends Person {
personalnummer: string;
abteilung: string;
}
const mitarbeiter: Mitarbeiter = {
vorname: "Bernd",
nachname: "Möller",
personalnummer: "MA-042",
abteilung: "Entwicklung",
};
Bei Type Aliases wird das kaufmännische Und zur Schnittmengenbildung (Intersection) verwendet:
type Person = {
vorname: string;
nachname: string;
};
type Mitarbeiter = Person & {
personalnummer: string;
abteilung: string;
};
Beide Varianten erzeugen funktional denselben Typ. Die Syntax unterscheidet sich, das Ergebnis ist dasselbe.
Declaration Merging
Hier liegt ein wesentlicher Unterschied. Interfaces können mehrfach deklariert werden. TypeScript führt die Deklarationen automatisch zusammen:
interface Konfiguration {
host: string;
port: number;
}
interface Konfiguration {
timeout: number; // Wird zur ersten Deklaration hinzugefügt
}
const config: Konfiguration = {
host: "localhost",
port: 3000,
timeout: 5000, // Alle drei Felder sind jetzt erforderlich
};
Bei Type Aliases ist das nicht möglich. Eine erneute Deklaration desselben Namens führt zu einem Compilerfehler:
type Konfiguration = {
host: string;
};
// Compilerfehler: Duplicate identifier 'Konfiguration'
type Konfiguration = {
timeout: number;
};
Declaration Merging ist besonders nützlich, wenn man Typen aus externen Bibliotheken erweitern möchte, ohne deren Quellcode zu ändern.
Readonly und Index Signatures
Beide Konstrukte unterstützen readonly-Felder und Index-Signaturen:
interface Einstellungen {
readonly erstellt: Date; // Kann nach der Erstellung nicht geändert werden
[schlüssel: string]: unknown; // Erlaubt beliebige weitere Felder
}
type Wörterbuch = {
readonly version: string;
[wort: string]: string;
};
Funktionen beschreiben
Interfaces können auch Funktionssignaturen definieren:
interface Transformierer {
(eingabe: string): string;
}
const großschreiben: Transformierer = (text) => text.toUpperCase();
// Mit Type Alias:
type TransformierFunktion = (eingabe: string) => string;
const kleinschreiben: TransformierFunktion = (text) => text.toLowerCase();
Wann Interface, wann Type Alias?
Die Entscheidung folgt einigen praktischen Richtlinien:
Interface verwenden, wenn:
- Eine Objektstruktur beschrieben wird und Erweiterbarkeit gewünscht ist
- Klassen die Struktur implementieren sollen (
implements) - Bibliothekstypen erweiterbar sein sollen
class BenutzerService implements Kunde {
id: number;
name: string;
email: string;
constructor(id: number, name: string, email: string) {
this.id = id;
this.name = name;
this.email = email;
}
}
Type Alias verwenden, wenn:
- Union Types, Intersection Types oder Tupel benötigt werden
- Primitive Typen einen sprechenden Namen bekommen sollen
- Literaltypen kombiniert werden
type Ergebnis<T> = { erfolg: true; daten: T } | { erfolg: false; fehler: string };
type NichtLeererString = string & { readonly brand: unique symbol };
Interoperabilität
Ein häufiger Irrtum ist, dass Interface und Type Alias nicht miteinander kombiniert werden können. Tatsächlich funktioniert das problemlos:
interface Basis {
id: number;
}
type Erweiterung = Basis & {
name: string;
};
interface Vollständig extends Erweiterung {
email: string;
}
Auf typescript-playground.de lassen sich beide Konstrukte direkt im Browser ausprobieren und vergleichen. Das ist besonders hilfreich, um das Verhalten bei Declaration Merging und Intersection Types zu verstehen.
Fazit
Interface und Type Alias sind zwei Werkzeuge für verwandte, aber unterschiedliche Aufgaben. Interfaces eignen sich für erweiterbare Objektstrukturen, Type Aliases für komplexe Typen wie Unions und Tupel. In vielen Projekten kommen beide zum Einsatz, und das ist völlig in Ordnung. Wichtiger als die Wahl zwischen beiden ist die konsistente Anwendung innerhalb eines Projekts.
Häufige Fragen
Was ist der wichtigste praktische Unterschied zwischen interface und type?
Interfaces können durch erneute Deklaration erweitert werden (Declaration Merging), Type Aliases nicht. Außerdem können Type Aliases für primitive Typen, Union Types und Tupel verwendet werden, während Interfaces nur Objektstrukturen beschreiben.
Kann ich interface und type miteinander kombinieren?
Ja, ein Interface kann von einem Type Alias erben und umgekehrt. Sie sind vollständig interoperabel.
Welche Option wird in der TypeScript-Community häufiger empfohlen?
Die offiziellen TypeScript-Docs empfehlen interfaces für Objekttypen, da sie erweiterbar sind. Type Aliases werden bevorzugt, wenn Union Types, Literal Types oder Tupel benötigt werden.
Quellen
- TypeScript Handbook: Object Types – typescriptlang.org
- TypeScript FAQ: Should I use interface or type? – github.com/microsoft/TypeScript
Über die Autorenschaft
Jan-Tristan Rudat
Redakteur typescript-playground.de
Themengebiet: Generationen, Kulturgeschichte, Sternzeichen, Pop-Phänomene rund ums Alter
Mehr über Jan-Tristan Rudat →Verwandte Artikel
Grundlagen
Was ist TypeScript? Eine Einführung in die typisierte JavaScript-Erweiterung
TypeScript erweitert JavaScript um statische Typen und macht große Codebases wartbarer. Lerne die Grundlagen, die Geschichte und die wichtigsten Vorteile von TypeScript.
Lesezeit 7 Min.
Grundlagen
TypeScript vs. JavaScript: Die wichtigsten Unterschiede im Überblick
TypeScript und JavaScript unterscheiden sich grundlegend in der Typprüfung, Werkzeugunterstützung und Wartbarkeit. Dieser Ratgeber erklärt die Unterschiede und hilft bei der Wahl der richtigen Sprache.
Lesezeit 8 Min.
Typen
TypeScript Typen Grundlagen: string, number, boolean und mehr
Die primitiven Typen string, number und boolean sind das Fundament von TypeScript. Dieser Ratgeber erklärt alle grundlegenden Typen mit praktischen Beispielen.
Lesezeit 9 Min.