Menu

TypeScript vs JavaScript: Die Unterschiede mit Beispielen

TypeScript ist JavaScript plus ein statisches Typsystem, das geprüft wird, bevor der Code läuft. Der Unterschied im direkten Vergleich: Syntax, was die Typprüfung findet, der Build-Schritt, Geschwindigkeit, Lernkurve und wie du ein JavaScript-Projekt migrierst.

Diese Seite enthält ausführbare Editoren - bearbeiten, ausführen und Ausgabe sofort sehen.

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

JavaScriptTypeScript
TypsystemDynamisch: Typen gehören zu Werten und sind erst zur Laufzeit bekanntStatisch: Typen werden deklariert oder abgeleitet und beim Kompilieren geprüft
Wann Typfehler auftauchenWenn die Zeile läuft (undefined, NaN, TypeError)Im Editor beim Tippen und beim Kompilieren
Läuft inBrowsern, Node.js, Deno, Bun, direktDenselben Umgebungen, nachdem die Typen entfernt sind
Build-SchrittNicht nötigtsc oder ein Bundler, oder eine Runtime, die Typen selbst entfernt
Dateien.js, .mjs, .cjs.ts, .mts, .cts, .tsx, dazu .d.ts-Typdeklarationen
Geschwindigkeit zur LaufzeitAusgangswertIdentisch: Die Ausgabe ist JavaScript
Editor-UnterstützungAutovervollständigung aus abgeleiteten Typen und Bibliothekstypen, die unvollständig sein könnenAutovervollständigung, Umbenennen und „Alle Verweise suchen“ aus deklarierten Typen
LernkurveNiedrigerJavaScript plus das Typsystem
StandardECMAScript, von TC39Ein 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/lodash fügt Typen für lodash hinzu.
  • Keine. Dann ist mit strict schon 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:

  • tsc kompiliert alles. Es prüft die Typen und schreibt .js-Dateien, meist in einen Ordner dist. Einfach, und der Standard für Bibliotheken.
  • Ein Bundler oder Dev-Server entfernt die Typen, und tsc --noEmit prü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 mit tsc --noEmit (oder deno 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:

  1. Annotationen an Variablen, Parametern und Rückgabewerten (: string, : number[]).
  2. Objekttypen mit interface und type, optionale Eigenschaften, Unions wie string | number.
  3. Narrowing: einen Wert mit typeof, in oder === prüfen, damit der Compiler weiß, in welchem Fall du bist.
  4. Generics, Utility Types wie Partial<T> und Pick<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-check und 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:

  1. Benenne eine Datei von .js in .ts um und behebe die Fehler, die der Compiler darin meldet.
  2. Fang bei den Blättern an (Hilfsmodule mit wenigen Importen) und arbeite dich nach innen vor.
  3. Schalte checkJs ein oder setze // @ts-check an 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.

Coddy programming languages illustration

Lerne mit Coddy zu programmieren

LOS GEHT'S