Fortgeschritten
TypeScript Type Inference verstehen
Wie TypeScript Typen automatisch ableitet, wann du explizite Annotationen brauchst und wie du das Typsystem optimal nutzt.
Inhalt
TypeScript Type Inference verstehen
TypeScript kann in den meisten Situationen automatisch den richtigen Typen ableiten, ohne dass du ihn explizit angeben musst. Dieses Feature nennt sich Type Inference und ist einer der Hauptgründe, warum TypeScript so produktiv macht: Du bekommst vollständige Typsicherheit, ohne überall Annotationen schreiben zu müssen.
Was ist Type Inference?
Type Inference bedeutet, dass der TypeScript-Compiler den Typen eines Ausdrucks anhand seines Wertes oder seiner Verwendung bestimmt. Das funktioniert in beide Richtungen: Der Compiler schaut sich an, was du zuweist, und leitet daraus ab, was erlaubt ist.
// TypeScript leitet 'number' ab
let alter = 25;
// Fehler: Type 'string' is not assignable to type 'number'
alter = "fünfundzwanzig";
Im Playground kannst du das direkt ausprobieren: Fahre einfach mit der Maus über eine Variable, um den abgeleiteten Typen zu sehen.
Contextual Typing
Type Inference funktioniert nicht nur bei Variablendeklarationen, sondern auch im Kontext von Funktionsparametern. TypeScript nennt das Contextual Typing.
const zahlen = [1, 2, 3, 4, 5];
// TypeScript weiß, dass 'n' ein 'number' ist
const verdoppelt = zahlen.map((n) => n * 2);
// TypeScript weiß, dass 'event' ein 'MouseEvent' ist
document.addEventListener("click", (event) => {
console.log(event.clientX);
});
Der Compiler analysiert, welchen Typ der Callback-Parameter haben muss, und gibt diesen Kontext nach innen weiter. Du musst n oder event nicht manuell annotieren.
Literal Types und das as const Problem
Hier liegt ein häufiger Stolperstein: Der Unterschied zwischen let und const beeinflusst den abgeleiteten Typen erheblich.
// Typ: string (veränderbar, daher breit)
let status = "aktiv";
// Typ: "aktiv" (unveränderbar, daher eng)
const status2 = "aktiv";
// Objekte mit 'as const' einfrieren
const konfiguration = {
host: "localhost",
port: 3000,
} as const;
// Typ: { readonly host: "localhost"; readonly port: 3000 }
Das as const Assertion ist besonders nützlich, wenn du ein Objekt als Konfiguration verwendest und sicherstellen willst, dass niemand die Werte versehentlich ändert.
Rückgabetypen von Funktionen
TypeScript leitet Rückgabetypen von Funktionen automatisch ab, wenn du alle Pfade berücksichtigst.
function berechneRabatt(preis: number, rabatt: number) {
if (rabatt > 100) {
return null;
}
return preis * (1 - rabatt / 100);
}
// Abgeleiteter Rückgabetyp: number | null
Sobald eine Funktion in einer Bedingung null zurückgibt, ergänzt TypeScript den Rückgabetypen automatisch um null. Das zwingt dich dazu, an den Aufrufstellen mit beiden Fällen umzugehen.
Wann explizite Annotationen sinnvoll sind
Type Inference ist mächtig, aber nicht in allen Situationen ausreichend. Explizite Annotationen sind sinnvoll bei:
Öffentlichen Funktions-Signaturen: Wer deine Funktion aufruft, sieht in der IDE sofort, was erwartet wird und was zurückkommt.
function begruesseNutzer(name: string, alter: number): string {
return `Hallo ${name}, du bist ${alter} Jahre alt.`;
}
Leeren Arrays: TypeScript leitet never[] ab, wenn du ein leeres Array deklarierst, ohne es sofort zu befüllen.
// Fehler: TypeScript leitet 'never[]' ab
const liste = [];
// Korrekt
const liste: string[] = [];
Komplexen Objekten mit optionalen Feldern: Wenn du ein Objekt schrittweise aufbaust, hilft eine Interface-Annotation, fehlende Felder schon beim Schreiben zu erkennen.
interface Nutzer {
id: number;
name: string;
email?: string;
}
const neuerNutzer: Nutzer = {
id: 1,
name: "Anna",
};
Type Widening verstehen
TypeScript verwendet standardmäßig den breitesten sinnvollen Typen, wenn es Unsicherheit gibt. Dieses Verhalten nennt sich Type Widening.
let wert = Math.random() > 0.5 ? "ja" : 42;
// Abgeleiteter Typ: string | number
Manchmal willst du das einschränken. Dann hilft ein expliziter Typ oder eine Typassertion.
const antwort = (Math.random() > 0.5 ? "ja" : "nein") as "ja" | "nein";
Praktisches Beispiel im Playground
Im Playground siehst du sofort, wie TypeScript über deine Variablen denkt. Schreibe eine Funktion, halte die Maus über den Rückgabewert und beobachte, was TypeScript ableitet. Das ist einer der besten Wege, das Typsystem intuitiv zu verstehen.
function summiereWerte(werte: number[]) {
return werte.reduce((acc, val) => acc + val, 0);
}
// Abgeleiteter Rückgabetyp: number
const gesamt = summiereWerte([10, 20, 30]);
Fazit
Type Inference macht TypeScript produktiv, ohne Typsicherheit zu opfern. Du musst nicht jeden Typen manuell annotieren, aber du solltest verstehen, wann TypeScript Hilfe braucht. Explizite Annotationen bei Funktions-Signaturen und leeren Datenstrukturen sind gute Praxis. Alles andere kannst du dem Compiler überlassen.
Häufige Fragen
Wann sollte ich explizite Typannotationen verwenden, obwohl TypeScript den Typ ableiten kann?
Immer dann, wenn die abgeleitete Typdefinition zu breit oder zu unspezifisch ist. Bei öffentlichen Funktions-Signaturen, exportierten Werten und komplexen Rückgabewerten lohnt sich eine explizite Annotation, weil sie die API dokumentiert und zukünftige Änderungen absichert.
Warum leitet TypeScript manchmal den Typ 'string' statt eines String-Literals ab?
Variablen, die mit 'let' deklariert werden, erhalten den allgemeinen Typen, weil ihr Wert veränderbar ist. Mit 'const' oder dem 'as const'-Assertion leitet TypeScript den engsten möglichen Typen ab.
Quellen
- TypeScript Handbook: Type Inference (typescriptlang.org)
Ü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
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.