Dein erstes TypeScript-Programm braucht keinen aufwendigen Setup. Eine einzige .ts-Datei, ein Aufruf von tsc und du hast lauffähiges JavaScript in der Hand. In diesem Artikel gehen wir den vollen Weg vom Quelltext bis zum ausgeführten Programm: Datei schreiben, kompilieren, in Node.js ausführen, im --watch-Modus arbeiten und als moderne Alternative tsx kennenlernen, das den Kompilier-Schritt komplett überspringt. Anschließend provozieren wir bewusst einen Typfehler, um zu sehen, was der Compiler meldet — und werfen einen kurzen Blick auf den Browser-Workflow. Eine tsconfig.json brauchst du dafür noch nicht; die kommt erst, wenn das Projekt wächst.

Voraussetzungen

Bevor du loslegst, sollten zwei Dinge auf deinem System bereitstehen:

  • Node.js in einer aktuellen LTS-Version. Prüfen mit node --version. Falls noch nicht installiert, hol es dir von nodejs.org oder über einen Version-Manager wie nvm, fnm oder volta.
  • TypeScript als globales oder projektlokales npm-Paket. Die Installation und die Funktionsweise von tsc sind im vorherigen Artikel Setup und tsc ausführlich beschrieben.

Ein schneller Check, ob alles vorhanden ist:

bash terminal
node --version
npx tsc --version
Output
v22.11.0
Version 5.6.3

Die konkreten Versionsnummern sind unkritisch — solange Node mindestens 18 und TypeScript mindestens 5 zeigt, bist du im grünen Bereich. Einen Editor brauchst du natürlich auch; VS Code bringt TypeScript-Support out of the box mit.

Die erste .ts-Datei

Lege ein leeres Verzeichnis an und darin eine Datei hello.ts. Das t in der Endung ist alles, was die Datei von normalem JavaScript unterscheidet — Editor und Compiler erkennen daran, dass sie Typen erwarten dürfen:

bash terminal
mkdir hello-ts
cd hello-ts
touch hello.ts

Öffne die Datei und schreibe ein klassisches Hello-World. Wir nehmen zusätzlich eine typisierte Variable mit, damit du den entscheidenden Unterschied zu reinem JavaScript siehst:

ts hello.ts
const gruss: string = "Hallo, TypeScript!";
const jahr: number = 2026;

function begruessen(name: string): string {
    return `${gruss} Willkommen, ${name} (${jahr}).`;
}

console.log(begruessen("Michael"));

Drei Dinge sind hier neu gegenüber JavaScript:

  • Typannotationen wie : string und : number hinter dem Namen einer Variable oder eines Parameters.
  • Rückgabetyp der Funktion (: string nach der Parameterliste).
  • Sonst nichts — der Rest ist gewöhnliches JavaScript. TypeScript ist ein Superset: jedes gültige JS ist auch gültiges TS.

Die Typannotationen sind in diesem Beispiel sogar redundant, weil TypeScript die Typen aus den Literalen ableiten könnte. Für den Einstieg machen sie aber die Intention sichtbar.

Kompilieren mit tsc

Der TypeScript-Compiler heisst tsc. Sein Hauptjob besteht aus zwei Schritten: Typen prüfen und anschließend reine .js-Dateien erzeugen, in denen alle Typannotationen entfernt sind. Diesen Vorgang nennt man Type Erasure — Typen existieren nur zur Compile-Zeit, nie zur Laufzeit.

Ruf den Compiler auf deine Datei auf:

bash terminal
npx tsc hello.ts
Output
(kein Output bei Erfolg)

Schweigen heißt: alles in Ordnung. Schau in das Verzeichnis — neben hello.ts liegt jetzt eine neue Datei hello.js:

bash terminal
ls
Output
hello.js  hello.ts

Der Inhalt von hello.js ist sauberes, lauffähiges JavaScript ohne jede Typinformation:

ts hello.js
"use strict";
const gruss = "Hallo, TypeScript!";
const jahr = 2026;
function begruessen(name) {
    return `${gruss} Willkommen, ${name} (${jahr}).`;
}
console.log(begruessen("Michael"));

Genau diese Datei kann jede JavaScript-Runtime ausführen — Node.js, Browser, Deno, Bun. Die Annotationen sind weg, der Code ist identisch zu dem, was du auch handgeschrieben hättest.

Die kompilierte Datei ausführen

Da wir keinen DOM-Code geschrieben haben, läuft das Programm direkt in Node.js:

bash terminal
node hello.js
Output
Hallo, TypeScript! Willkommen, Michael (2026).

Das ist der vollständige TypeScript-Workflow in zwei Befehlen: erst tsc, dann node. Mehr brauchst du nicht für einen ersten Erfolg. Bei jeder Änderung an hello.ts musst du allerdings beide Schritte erneut ausführen — und genau dafür gibt es den Watch-Mode.

Watch-Mode

Mit der Option --watch (oder kurz -w) bleibt tsc im Hintergrund, beobachtet deine Datei und kompiliert bei jeder Speicherung automatisch neu. Das verkürzt die Feedback-Schleife auf praktisch null:

bash terminal
npx tsc --watch hello.ts
Output
[12:00:00] Starting compilation in watch mode...
[12:00:01] Found 0 errors. Watching for file changes.

Sobald du hello.ts speicherst, gibt der Compiler eine neue Statuszeile aus — entweder mit Found 0 errors (Erfolg) oder mit einer Fehlerliste. Die hello.js daneben aktualisiert sich automatisch. Beende den Watcher mit Ctrl+C.

Du kannst den Watcher in einem zweiten Terminal laufen lassen und in einem dritten Terminal node hello.js ausführen, sooft du willst. Klassisches Setup:

bash terminal (Layout-Idee)
# Terminal A — Watch-Compiler
npx tsc --watch hello.ts

# Terminal B — Programm starten
node hello.js

Sobald dein Projekt aus mehreren Dateien besteht und du eine tsconfig.json hast, genügt sogar ein nacktes npx tsc --watch — der Compiler kennt dann alle Quellen automatisch.

Direkt ausführen mit tsx

Der explizite Zweischritt aus tsc + node ist transparent, aber für die tägliche Entwicklung umständlich. Hier kommt tsx ins Spiel — ein Tool, das TypeScript-Dateien on the fly kompiliert und sofort in Node.js ausführt. Keine .js-Datei wird auf die Platte geschrieben, kein Watch-Prozess muss laufen.

bash terminal
npx tsx hello.ts
Output
Hallo, TypeScript! Willkommen, Michael (2026).

tsx benutzt intern den schnellen Bundler esbuild, weshalb der Start praktisch ohne Verzögerung erfolgt. Auch einen Watch-Mode bringt es mit:

bash terminal
npx tsx watch hello.ts

Wann nimmst du was?

ToolZweckOutputWann sinnvoll
tscBuild & Typprüfungerzeugt .js-DateienProduction-Build, CI, Library-Veröffentlichung
tsxDirektausführungnichts auf PlatteEntwicklung, Skripte, schnelle Iteration

Wichtig: tsx führt kein vollständiges Type-Checking durch — es transpiliert nur. Du solltest in deinem Projekt zusätzlich tsc --noEmit als Check-Befehl behalten (oder einen Editor mit aktiver TypeScript-Sprache wie VS Code), damit Typfehler nicht unbemerkt durchrutschen.

Erste Typfehler bewusst erzeugen

Damit du siehst, was TypeScript überhaupt für dich tut, brechen wir die Datei absichtlich. Ändere hello.ts so, dass an einer Stelle ein falscher Typ landet:

ts hello.ts (kaputt)
const gruss: string = "Hallo, TypeScript!";
const jahr: number = "2026";

function begruessen(name: string): string {
    return `${gruss} Willkommen, ${name} (${jahr}).`;
}

console.log(begruessen(42));

Zwei Fehler steckten gleich drin: jahr wird mit einem String belegt, obwohl number deklariert ist, und begruessen bekommt eine Zahl statt eines Strings. Der Compiler meldet beides klar:

bash terminal
npx tsc hello.ts
Output
hello.ts:2:7 - error TS2322: Type 'string' is not assignable to type 'number'.

2 const jahr: number = "2026";
        ~~~~

hello.ts:8:24 - error TS2345: Argument of type 'number' is not assignable
to parameter of type 'string'.

8 console.log(begruessen(42));
                         ~~

Found 2 errors in the same file, starting at: hello.ts:2

Beachte das Verhalten genau: Trotz Fehler wird hello.js aktualisiert. Das ist Absicht — TypeScript will dich bei der Migration aus reinem JavaScript nicht aufhalten. Möchtest du dieses Verhalten unterbinden, ergänze die Flag --noEmitOnError:

bash terminal
npx tsc --noEmitOnError hello.ts

Jetzt bleibt die .js-Datei unverändert, solange Typfehler bestehen. In einer tsconfig.json schaltest du dasselbe per "noEmitOnError": true.

Browser-Variante (optional)

Wenn dein Hello-World im Browser laufen soll statt in Node.js, ändert sich nur der Output-Code und das Einbinden. Schreibe statt console.log einen DOM-Zugriff:

ts hello.ts
const gruss: string = "Hallo, TypeScript!";

function begruessen(name: string): string {
    return `${gruss} Willkommen, ${name}.`;
}

document.body.textContent = begruessen("Michael");

Kompiliere wie gewohnt und verlinke die erzeugte .js-Datei in einer einfachen HTML-Seite:

html index.html
<!doctype html>
<html lang="de">
    <head>
        <meta charset="utf-8" />
        <title>Hello TypeScript</title>
    </head>
    <body>
        <script src="hello.js"></script>
    </body>
</html>

Öffne die HTML-Datei im Browser — der Begrüßungstext erscheint. Für ernsthafte Browser-Projekte wirst du später nicht mehr direkt tsc verwenden, sondern einen Bundler wie Vite, esbuild oder Rollup, der TypeScript transparent mitübersetzt. Das Grundprinzip — .ts rein, .js raus — bleibt aber dasselbe.

FAQ

Warum wird trotz Compile-Fehler eine .js-Datei erzeugt?

Das ist Default-Verhalten und Absicht: TypeScript ist als sanfter Migrationspfad aus JavaScript gedacht. Selbst wenn der Type-Check meckert, bekommst du lauffähigen JS-Output. Möchtest du das verhindern, setz das Flag --noEmitOnError auf der Kommandozeile oder "noEmitOnError": true in deiner tsconfig.json.

Wo landet die .js-Datei standardmäßig?

Ohne tsconfig.json legt tsc die kompilierte Datei direkt neben die Quelle. Aus src/hello.ts wird also src/hello.js. Sobald du eine Konfiguration nutzt, steuern die Optionen outDir und rootDir die Verzeichnisstruktur — typisch ist dann dist/ als Ziel.

Brauche ich eine tsconfig.json für das Hello-World?

Nein. Für eine einzelne Datei genügt der direkte Aufruf tsc hello.ts. Sobald dein Projekt aus mehreren Dateien besteht, du strikte Checks aktivieren möchtest oder ein klares Verzeichnis-Layout brauchst, wird eine tsconfig.json aber schnell unverzichtbar. Erzeugen lässt sie sich mit npx tsc --init.

Was ist der Unterschied zwischen tsc und tsx?

tsc ist der offizielle TypeScript-Compiler. Er prüft Typen vollständig und schreibt .js-Dateien auf die Platte — das richtige Werkzeug für Builds. tsx ist ein Drittanbieter-Tool, das auf esbuild aufbaut, TypeScript on the fly transpiliert und sofort ausführt. Es ist schnell und bequem, macht aber keinen Type-Check — ideal für Entwicklung und Skripte, nicht für Production-Builds.

Funktioniert das auch mit Bun oder Deno?

Ja, beide Runtimes verstehen TypeScript nativ. Mit Bun reicht bun run hello.ts, mit Deno deno run hello.ts. Es ist kein vorgelagerter Kompilierschritt nötig, und auch hier sind die Typen zur Laufzeit irrelevant — sie werden intern entfernt, bevor der Code ausgeführt wird.

Wie debugge ich TypeScript?

Mit Source Maps. Übergib --sourceMap an tsc (oder setze "sourceMap": true in der tsconfig.json); dann erzeugt der Compiler zusätzlich eine .js.map-Datei. Damit zeigen Browser-DevTools und der Node-Debugger Breakpoints in deinem Original-TypeScript an, obwohl tatsächlich das transpilierte JavaScript läuft.

Was bedeutet die Warnung über module oder target?

Ohne tsconfig.json wählt tsc konservative Defaults — meist ein älteres ECMAScript-Target und CommonJS als Modul-Format. Ab TypeScript 5 weist der Compiler manchmal darauf hin, dass die Defaults veraltet sind. Die Lösung: npx tsc --init ausführen und in der erzeugten Konfiguration target und module auf moderne Werte wie ES2022 bzw. NodeNext setzen.

Weiterführende Ressourcen

Externe Quellen

/ Weiter

Zurück zu Grundlagen

Zur Übersicht