TypeScript vs. JavaScript: was sich ändert, was tsc ausgibt | We.Inc
Sieh TypeScript und das daraus kompilierte JavaScript nebeneinander, erfahre, was der Type Checker findet, warum Typen zur Laufzeit verschwinden und wann einfaches JavaScript reicht.
TypeScript ist JavaScript plus ein Typsystem. Du schreibst normales JavaScript mit optionalen Typannotationen, und der Compiler tsc prüft sie und entfernt sie dann, um reines JavaScript zu erzeugen. Browser und Node führen diese Ausgabe aus, daher existieren Typen zur Laufzeit nie. Der Gewinn liegt darin, Fehler schon beim Bearbeiten zu finden, nicht in schnellerem Code.
Im direkten Vergleich
Frage
JavaScript
TypeScript
Läuft direkt im Browser?
Ja
Nein, wird zuerst zu JavaScript kompiliert oder davon befreit
Wann werden Typfehler gefunden?
Wenn der Code läuft
Beim Bearbeiten und bei der Prüfung durch tsc
Dateiendungen
.js, .mjs, .jsx
.ts, .tsx (.d.ts für Deklarationen)
Typen zur Laufzeit
Nur Werte
Keine, Annotationen werden entfernt
Build-Schritt nötig?
Optional
Ja für die Prüfung; ein Stripper oder Bundler zum Ausführen
Gültiges JavaScript ist gültige Eingabe?
Ja
Ja, auch wenn der Checker Fehler melden kann
Wähle unten ein Beispiel, um eine TypeScript-Datei neben dem JavaScript zu sehen, das tsc daraus geschrieben hat. Meistens ist die Ausgabe dein Code ohne die Annotationen. Einige Features, etwa Enums, erzeugen echten Code, und dieser Unterschied spielt bei der Wahl deiner Tools eine Rolle.
Wähle ein Beispiel: einfache Annotationen, ein Interface, ein Enum, ein const enum oder einen Typfehler.
Lies links den TypeScript-Quellcode und rechts das erzeugte JavaScript.
Lies den Hinweis unter jedem Paar, um zu sehen, was der Compiler geprüft hat und was in der Ausgabe übrig bleibt.
Kopiere eine der beiden Seiten, um sie in deinem eigenen Projekt auszuprobieren.
Lege vom ersten Tag an eine tsconfig.json mit strict auf true an. Wenn du es später in einer großen Codebasis aktivierst, tauchen Hunderte Fehler auf einmal auf.
Benenne bei einer Migration jeweils eine .js-Datei in .ts um. Mit allowJs können beide Dateiarten während der Umstellung im selben Projekt leben.
Denk daran, dass JSON von einem Server untypisiert ist, bis du es prüfst. Eine Typannotation an abgerufenen Daten ist ein Versprechen an den Compiler, keine Prüfung zur Laufzeit.
Verwende zum Ausführen einen schnellen Stripper (Vite, esbuild oder das Type Stripping von Node) und lass tsc --noEmit als separate Prüfung in deinem Editor und in der CI laufen.
Häufige Fragen
Ist TypeScript eine andere Sprache als JavaScript?
Es ist eine Obermenge. Jedes TypeScript-Programm wird zu JavaScript, und TypeScript ergänzt Syntax, um die Form von Werten zu beschreiben. Lerne zuerst JavaScript; die Typen setzen darauf auf, statt es zu ersetzen.
Macht TypeScript meine Website schneller?
Nein. Annotationen werden entfernt, bevor der Code läuft, daher führt der Browser dasselbe JavaScript aus, das du von Hand geschrieben hättest. Die Vorteile sind weniger Bugs, die bei Nutzern ankommen, und sichereres Refactoring.
Verweigert tsc den Build, wenn es einen Typfehler gibt?
Standardmäßig nicht. tsc meldet den Fehler und schreibt trotzdem die .js-Datei, was eine schrittweise Migration möglich macht. Setze noEmitOnError, wenn eine fehlgeschlagene Prüfung die Ausgabe blockieren soll.
Kann Node .ts-Dateien ohne Build-Schritt ausführen?
Aktuelle Node-Versionen entfernen löschbare Typsyntax und führen die Datei aus; Type Stripping ist seit v23.6.0 und v22.18.0 standardmäßig aktiv. Node prüft keine Typen, und Syntax, die generierten Code braucht, etwa Enums, wird abgelehnt.
Wann ist einfaches JavaScript die bessere Wahl?
Kleine Skripte, schnelle Prototypen und Seiten mit ein paar Zeilen Interaktivität rechtfertigen den Einrichtungsaufwand selten. Sobald ein Projekt mehrere Dateien, mehrere Beteiligte oder Daten hat, die zwischen Modulen weitergereicht werden, spart der Checker spürbar Zeit.
Was tsc tatsächlich macht
Der Compiler hat zwei Aufgaben, die oft vermischt werden. Erstens prüft er Typen: Er liest jede Datei, ermittelt den Typ jedes Werts und meldet alles, was nicht passt. Zweitens erzeugt er Ausgabe: Er schreibt JavaScript ohne die Typsyntax und schreibt auf Wunsch neuere Syntax für ältere Ziele um.
Moderne Toolchains trennen diese Aufgaben meist. Ein Bundler wie Vite entfernt die Typen schnell, ohne etwas zu prüfen, und tsc --noEmit führt die vollständige Prüfung separat in deinem Editor oder in der CI aus. Wenn du nur den Bundler laufen lässt, können Typfehler ausgeliefert werden.
Typen werden entfernt, also prüfe echte Daten
Weil Annotationen verschwinden, kann TypeScript nicht verhindern, dass ein Server einen String schickt, wo du eine Zahl deklariert hast. const user: User = await res.json() sagt dem Checker nur, dass er dir vertrauen soll.
Prüfe an den Rändern deines Programms, etwa bei Formulareingaben, fetch-Antworten und Local Storage, den Wert zur Laufzeit mit einer kleinen Guard-Funktion oder einer Schema-Bibliothek, und lass den Checker diese Garantie nach innen weitertragen.
Features, die nicht einfach entfernt werden
Enums, Namespaces mit Code, Parameter Properties und import =-Aliase erzeugen alle eigenes JavaScript. TypeScript 5.8 hat die Option erasableSyntaxOnly eingeführt, die dafür einen Fehler meldet, damit eine Datei mit Type Strippern funktioniert, die nur Annotationen löschen.
Wenn du .ts-Dateien direkt in Node oder über einen anderen Stripper ausführen willst, bevorzuge Unions aus String-Literalen und as const-Objekte gegenüber Enums. Der Enum-Guide auf dieser Website zeigt beides nebeneinander.
TypeScript zu einem JavaScript-Projekt hinzufügen
Installieren und eine tsconfig anlegen
Installiert den Compiler lokal, schreibt eine Start-tsconfig.json und führt eine Prüfung aus, ohne Dateien zu schreiben.
allowJs lässt alte .js-Dateien während einer Migration neben neuen .ts-Dateien bestehen; noEmit überlässt die Ausgabe deinem Bundler.
Daten prüfen, die der Compiler nicht sieht
Ein Laufzeit-Guard, der den Typ eingrenzt
Die Funktion prüft den Wert wirklich, und der Rückgabetyp teilt dem Compiler mit, was sie bewiesen hat.
Annotationen
Parameter- und Rückgabetypen werden geprüft und dann gelöscht. Der Funktionsrumpf bleibt unverändert.
Interface
Ein Interface erzeugt überhaupt keine Ausgabe. Es existiert nur für den Checker.
Enum
Ein normales Enum wird zu einem echten Objekt mit umgekehrter Zuordnung, das ist also generierter Code und keine entfernte Syntax.
const enum
tsc setzt die Mitglieder eines const enum als Zahlen direkt ein und hinterlässt einen Kommentar mit dem ursprünglichen Namen.
Typfehler
tsc meldet: Argument of type 'string' is not assignable to parameter of type 'number'. Die Datei wird trotzdem geschrieben, sofern noEmitOnError nicht gesetzt ist.