TypeScript
Kurz: Eine von Microsoft entwickelte Obermenge von JavaScript, die statische Typisierung hinzufügt.
Genauer: Wird zu normalem JavaScript kompiliert (“transpiliert”), läuft also überall dort, wo JS läuft. Der Compiler prüft vor der Ausführung, ob Typen zusammenpassen (z. B. ob eine Funktion mit den richtigen Parametertypen aufgerufen wird), was viele Fehler schon während der Entwicklung statt erst zur Laufzeit auffängt.
Im Detail
Entstehung
TypeScript wurde 2012 von Microsoft veröffentlicht, unter Federführung von Anders Hejlsberg (der zuvor auch C# und Delphi mitentwickelt hatte). Der Auslöser: JavaScript wurde ursprünglich 1995 in nur zehn Tagen für kleine Skript-Aufgaben im Browser entworfen, ohne Typsystem — mit dem Aufstieg großer, komplexer JavaScript-Anwendungen (Single-Page-Apps, große Codebasen mit vielen Entwicklern) zeigten sich die Grenzen dieses Designs: Tippfehler in Objekteigenschaften, falsch übergebene Funktionsparameter oder undefined-Zugriffe fielen oft erst zur Laufzeit auf, manchmal erst beim Kunden. TypeScript sollte diese Fehlerklasse durch statische Typprüfung schon während der Entwicklung abfangen, ohne die Sprache JavaScript selbst zu ersetzen.
Eine echte Obermenge
function begruesse(name: string, alter: number): string {
return `Hallo ${name}, du bist ${alter} Jahre alt.`;
}
begruesse("Anna", "dreißig"); // Compiler-Fehler: Argument vom Typ "string" ist
// dem Parameter vom Typ "number" nicht zuweisbar“Obermenge” bedeutet konkret: Jede gültige JavaScript-Datei ist automatisch auch gültiges TypeScript (die Dateiendung ändert sich, der Code nicht) — man kann bestehenden JS-Code schrittweise, Datei für Datei, zu TypeScript migrieren, statt alles auf einmal umschreiben zu müssen. Der zweite Aufruf im Beispiel würde in reinem JavaScript stillschweigend ein falsches Ergebnis produzieren (z. B. NaN bei einer nachfolgenden Rechenoperation) und den Fehler erst zur Laufzeit sichtbar machen, oft an einer ganz anderen Stelle im Programm als der eigentlichen Ursache. TypeScript meldet den Typkonflikt dagegen schon beim Kompilieren — und praktisch immer schon live im Editor durch eine rote Unterstreichung, lange bevor der Code überhaupt ausgeführt wird.
Strukturelle statt nominale Typisierung
interface Punkt { x: number; y: number; }
function entfernungVomUrsprung(p: Punkt): number {
return Math.sqrt(p.x ** 2 + p.y ** 2);
}
// Funktioniert, obwohl "objekt" nie explizit als "Punkt" deklariert wurde -
// die FORM passt, das reicht.
const objekt = { x: 3, y: 4, farbe: "rot" };
entfernungVomUrsprung(objekt);TypeScripts Typsystem ist “strukturell”: Zwei Werte gelten als kompatibel, wenn sie dieselbe Form (dieselben Felder mit passenden Typen) haben — unabhängig davon, ob sie explizit als derselbe Typ deklariert wurden, und selbst wenn (wie im Beispiel) zusätzliche Felder vorhanden sind. Das unterscheidet TypeScript von “nominal” typisierten Sprachen wie Java oder C#, wo zwei Objekte nur dann kompatibel sind, wenn sie über denselben deklarierten Klassennamen verbunden sind, selbst bei identischer Feldstruktur. Struktureller Typisierung liegt näher an JavaScripts ursprünglich dynamischer, “duck-typed” Natur (“wenn es wie eine Ente quakt…”) und macht die Integration mit bestehendem, untypisiertem JS-Code leichter.
Kompilieren, nicht interpretieren
TypeScript-Code läuft nirgends direkt — der TypeScript-Compiler (tsc) übersetzt ihn zunächst in reines JavaScript (Typannotationen werden dabei komplett entfernt, sie existieren nur zur Kompilierzeit), das dann ganz normal im Browser oder in Node.js ausgeführt wird. Das bedeutet auch: TypeScripts Typprüfung bietet keinerlei Schutz zur LAUFZEIT — Daten, die z. B. per fetch() von einer externen API kommen, können trotz eines angegebenen Typs zur Laufzeit eine völlig andere Form haben, wenn sich die API ändert; TypeScript vertraut den Typannotationen blind.
Typen für fremden Code
Für bestehende JavaScript-Bibliotheken, die selbst kein TypeScript nutzen, lassen sich Typen nachträglich über separate Deklarationsdateien (.d.ts) bereitstellen, ohne deren eigentlichen Code anzufassen — entweder von der Bibliothek selbst mitgeliefert oder über das Community-Projekt DefinitelyTyped (@types/paketname). Dadurch funktioniert TypeScript gut mit dem riesigen bestehenden JavaScript-Ökosystem, einschließlich Bibliotheken wie React, ohne dass dieses komplett neu geschrieben werden müsste.