TypeScript ist JavaScript mit einem zusätzlichen statischen Typsystem. Jedes JavaScript-Programm ist gültige TypeScript-Syntax; TypeScript fügt Typannotationen hinzu, einen Compiler, der sie prüft, bevor der Code läuft, und einen Build-Schritt, der sie wieder entfernt. Zur Laufzeit gibt es nur JavaScript, der Unterschied liegt also ganz darin, was du vor dem Ausliefern herausfindest.
In JavaScript ist dieselbe Funktion der Code ohne type Product = ..., : Product[] und : number. Die Typen liefern Informationen für den Compiler und den Editor; sie ändern nicht, was das Programm tut.
TypeScript vs JavaScript im Überblick
| JavaScript | TypeScript | |
|---|---|---|
| Typsystem | Dynamisch: Typen gehören zu Werten und sind erst zur Laufzeit bekannt | Statisch: Typen werden deklariert oder abgeleitet und beim Kompilieren geprüft |
| Wann Typfehler auftauchen | Wenn die Zeile läuft (undefined, NaN, TypeError) | Im Editor beim Tippen und beim Kompilieren |
| Läuft in | Browsern, Node.js, Deno, Bun, direkt | Denselben Umgebungen, nachdem die Typen entfernt sind |
| Build-Schritt | Nicht nötig | tsc oder ein Bundler, oder eine Runtime, die Typen selbst entfernt |
| Dateien | .js, .mjs, .cjs | .ts, .mts, .cts, .tsx, dazu .d.ts-Typdeklarationen |
| Geschwindigkeit zur Laufzeit | Ausgangswert | Identisch: Die Ausgabe ist JavaScript |
| Editor-Unterstützung | Autovervollständigung aus abgeleiteten Typen und Bibliothekstypen, die unvollständig sein können | Autovervollständigung, Umbenennen und „Alle Verweise suchen“ aus deklarierten Typen |
| Lernkurve | Niedriger | JavaScript plus das Typsystem |
| Standard | ECMAScript, von TC39 | Ein Open-Source-Projekt von Microsoft, das ECMAScript folgt |
Derselbe Code in beiden Sprachen
Hier ist eine Funktion in JavaScript. Nichts darin sagt, wie user aussehen muss:
function greeting(user) {
return `Hello, ${user.firstName} ${user.lastName}`;
}
greeting({ firstname: "Ada", lastName: "Lovelace" });
// "Hello, undefined Lovelace", no error anywhere
Die TypeScript-Version legt die Form einmal fest, und der Tippfehler wird gemeldet, bevor der Code läuft:
interface User {
firstName: string;
lastName: string;
}
function greeting(user: User): string {
return `Hello, ${user.firstName} ${user.lastName}`;
}
greeting({ firstname: "Ada", lastName: "Lovelace" });
// error TS2561: Object literal may only specify known properties,
// but 'firstname' does not exist in type 'User'. Did you mean to write 'firstName'?
Die Annotationen sind der gesamte Unterschied in der Syntax. TypeScript bringt außerdem ein paar eigene Deklarationen mit (interface, type, enum, Generics wie Array<string>, Zugriffsmodifizierer wie private), aber Anweisungen, Operatoren und eingebaute Objekte sind die von JavaScript.
Was TypeScript findet und JavaScript nicht
JavaScript wandelt Typen stillschweigend um. Dieser Fehler ist häufig bei Werten aus Formularfeldern, die immer Strings sind. Führe den Code aus und sieh dir an, was der Compiler sagt:
index.ts(7,17): error TS2345: Argument of type 'string[]' is not assignable to parameter of type 'number[]'.
Type 'string' is not assignable to type 'number'.
In JavaScript läuft das und gibt 010205 aus, weil 0 + "10" eine String-Verkettung ist. TypeScript kompiliert erst, wenn die Strings umgewandelt sind, zum Beispiel mit fromForm.map(Number).
Die andere große Kategorie sind Werte, die fehlen könnten. Array.prototype.find gibt undefined zurück, wenn nichts passt, und TypeScript zwingt dich, damit umzugehen:
index.ts(8,13): error TS18048: 'user' is possibly 'undefined'.
Die reine JavaScript-Version stürzt zur Laufzeit mit TypeError: Cannot read properties of undefined (reading 'name') ab. In TypeScript behandelst du den Fall, auf den der Compiler gezeigt hat:
Ausgabe:
GRACE
no user with id 3
Was TypeScript nicht findet: Logikfehler (eine falsche Formel hat den richtigen Typ) und alles, was Daten betrifft, die zur Laufzeit ins Programm kommen. Eine API-Antwort mit dem Typ User ist nur so korrekt wie der Server, der sie geschickt hat, denn die Typen sind weg, sobald der Code läuft. Prüfe solche Daten mit Laufzeitcode.
JavaScript-Bibliotheken in TypeScript verwenden
Jedes npm-Paket funktioniert mit TypeScript, weil die Ausgabe sowieso JavaScript ist. Die Typen für ein Paket kommen aus einer von drei Quellen:
- Das Paket liefert eigene
.d.ts-Dateien mit. Die meisten aktiv gepflegten Pakete tun das, und du installierst nichts zusätzlich. - Ein separates
@types-Paket aus dem Community-Projekt DefinitelyTyped:npm install --save-dev @types/lodashfügt Typen fürlodashhinzu. - Keine. Dann ist mit
strictschon der Import ein Fehler:
error TS7016: Could not find a declaration file for module 'lodash'. '/project/node_modules/lodash/lodash.js' implicitly has an 'any' type.
Try `npm i --save-dev @types/lodash` if it exists or add a new declaration (.d.ts) file containing `declare module 'lodash';`
Die Lösung ist, das @types-Paket zu installieren, falls es existiert, oder das Modul selbst in einer .d.ts-Datei zu beschreiben; die Seite zu Deklarationsdateien zeigt, wie.
Der Build-Schritt
Browser und Node.js prüfen keine Typen, also braucht TypeScript einen Schritt zwischen deinem Quellcode und dem Code, der läuft. Es gibt drei übliche Setups:
tsckompiliert alles. Es prüft die Typen und schreibt.js-Dateien, meist in einen Ordnerdist. Einfach, und der Standard für Bibliotheken.- Ein Bundler oder Dev-Server entfernt die Typen, und
tsc --noEmitprüft sie. Vite und esbuild entfernen Typen ohne Prüfung, was das Neuladen schnell hält; der Editor und ein CI-Schritt führen die Typprüfung aus. - Die Runtime entfernt die Typen. Aktuelle Node.js-Versionen, Deno und Bun führen
.ts-Dateien direkt aus. Keine davon prüft Typen beim Ausführen, also findest du Typfehler weiterhin mittsc --noEmit(oderdeno check).
JavaScript braucht nichts davon, und das ist sein größter praktischer Vorteil bei kleinen Skripten. Der TypeScript-Schritt kostet vor allem Einrichtung, eine tsconfig.json und eine typescript-Dev-Dependency, sowie Kompilierzeit; der native Compiler von TypeScript 7 hat diese Zeit bei großen Projekten etwa auf ein Zehntel gesenkt.
Lernkurve
Alles, was du über JavaScript weißt, gilt weiter, weil die Laufzeit von TypeScript JavaScript ist. Neu ist das Typsystem, und es kommt in Schichten:
- Annotationen an Variablen, Parametern und Rückgabewerten (
: string,: number[]). - Objekttypen mit
interfaceundtype, optionale Eigenschaften, Unions wiestring | number. - Narrowing: einen Wert mit
typeof,inoder===prüfen, damit der Compiler weiß, in welchem Fall du bist. - Generics, Utility Types wie
Partial<T>undPick<T, K>und fortgeschrittene Typen für Bibliotheksautoren.
Die ersten beiden Schichten decken den größten Teil von Anwendungscode ab. Vieles an der Typisierung wird abgeleitet, also sieht viel TypeScript-Code aus wie JavaScript mit Annotationen nur an den Funktionssignaturen.
Wann TypeScript und wann JavaScript
Ist TypeScript besser als JavaScript? Für Code, den mehrere Leute pflegen oder der jahrelang lebt, meistens ja, und die Branche hat sich in diese Richtung bewegt: Gemessen an der Zahl der monatlichen Mitwirkenden hat TypeScript im August 2025 JavaScript und Python überholt und ist die meistgenutzte Sprache auf GitHub. Für kleine Skripte ist reines JavaScript oft das bessere Werkzeug.
Wähle TypeScript, wenn:
- Mehr als eine Person am Code arbeitet oder er über Monate oder Jahre gepflegt wird.
- Die Codebasis so groß ist, dass du nicht jede Funktionssignatur im Kopf behalten kannst.
- Du oft refaktorierst: Das Umbenennen einer Eigenschaft ändert jede Verwendung, und der Compiler listet alles auf, was übrig bleibt.
- Du eine Bibliothek veröffentlichst: Die
.d.ts-Dateien geben ihren Nutzern Autovervollständigung und Prüfungen. - Das Framework es erwartet. Angular-Apps werden in TypeScript geschrieben, Next.js und Astro legen neue Projekte standardmäßig in TypeScript an, und die Vorlagen von Vite für React, Vue und Svelte gibt es jeweils in einer TypeScript-Variante.
Wähle JavaScript, wenn:
- Das Programm ein kurzes Skript, ein einmaliges Experiment oder ein Codeschnipsel in der Browserkonsole ist.
- Du zum ersten Mal programmieren lernst und weniger Konzepte auf einmal willst.
- Es keinen Build-Schritt gibt und du keinen willst. Selbst dann bekommst du mit
// @ts-checkund JSDoc eine gewisse Prüfung in einer normalen.js-Datei.
Ein JavaScript-Projekt zu TypeScript migrieren
Eine Migration muss nicht auf einmal passieren. Der Compiler akzeptiert JavaScript neben TypeScript:
{
"compilerOptions": {
"allowJs": true,
"checkJs": false,
"outDir": "dist",
"rootDir": "src"
},
"include": ["src"]
}
Mit allowJs werden .js-Dateien kompiliert und können aus .ts-Dateien importieren und umgekehrt. Dann stellst du schrittweise um:
- Benenne eine Datei von
.jsin.tsum und behebe die Fehler, die der Compiler darin meldet. - Fang bei den Blättern an (Hilfsmodule mit wenigen Importen) und arbeite dich nach innen vor.
- Schalte
checkJsein oder setze// @ts-checkan den Anfang einzelner.js-Dateien, um Dateien zu prüfen, die du noch nicht umbenannt hast.
In geprüften JavaScript-Dateien liefern JSDoc-Kommentare die Typen:
// @ts-check
/**
* @param {number} price
* @param {number} qty
* @returns {number}
*/
function lineTotal(price, qty) {
return price * qty;
}
lineTotal("3", 2);
// error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
Manche Teams hören dort auf: JavaScript-Dateien mit JSDoc-Typen, geprüft von tsc, und kein Build-Schritt für den Code selbst. Andere gehen den ganzen Weg zu .ts. Schaltest du strict in einem bestehenden Projekt ein, erwarte anfangs viele Fehler; die Seite zum Strict Mode listet auf, was jedes Flag prüft, damit du sie einzeln aktivieren kannst.
Häufig gestellte Fragen
Was ist der wichtigste Unterschied zwischen TypeScript und JavaScript?
TypeScript fügt JavaScript statische Typen hinzu. Du beschreibst, was jeder Wert ist (name: string, items: Item[]), und der TypeScript-Compiler meldet Fehler, bevor der Code läuft. JavaScript prüft vorab nichts: Ein falscher Typ fällt erst auf, wenn die Zeile ausgeführt wird, oft als undefined oder als TypeError.
Ist TypeScript besser als JavaScript?
Für die meisten Projekte, die mehr als eine Person pflegt oder die länger als ein paar Wochen leben, ja: Typen finden ganze Klassen von Fehlern, machen Refactoring sicher und liefern die Autovervollständigung im Editor. Für ein kurzes Skript, einen schnellen Prototyp oder eine Übung ist reines JavaScript schneller eingerichtet und braucht keinen Build.
Ist TypeScript schneller als JavaScript?
Nein, aber auch nicht langsamer. TypeScript wird zu JavaScript kompiliert und die Typen werden entfernt, also ist der ausgeführte Code dasselbe JavaScript, das du von Hand schreiben würdest. Die einzigen Zusatzkosten sind die Kompilierzeit während der Entwicklung.
Sollte ich zuerst JavaScript oder TypeScript lernen?
Lerne zuerst die Grundlagen von JavaScript oder beides zusammen. Das gesamte Laufzeitverhalten (Variablen, Funktionen, Objekte, Arrays, Promises) ist JavaScript, und TypeScript beschreibt es nur. Sobald du kleine JavaScript-Programme schreiben kannst, ist der Schritt zu Typen kurz.
Kann ich TypeScript und JavaScript im selben Projekt verwenden?
Ja. Setze "allowJs": true in tsconfig.json, dann akzeptiert der Compiler .js-Dateien neben .ts-Dateien. Füge "checkJs": true hinzu (oder pro Datei einen Kommentar // @ts-check), um auch die JavaScript-Dateien zu prüfen, mit Typen aus JSDoc-Kommentaren. So migriert man ein Projekt üblicherweise Datei für Datei.