ProCust
Full-Stack-Entwicklung mit TypeScript: Der praktische Leitfaden

Full-Stack-Entwicklung mit TypeScript: Der praktische Leitfaden

Full-Stack-Entwicklung mit TypeScript: gemeinsame Typen für Frontend und Backend, Laufzeitvalidierung, Datenbankzugriff, Projektstruktur und Tests.

Kurz gefasst: Full-Stack-Entwicklung mit TypeScript heißt, Frontend, Backend und oft auch Datenbankzugriff in einer Sprache zu schreiben und Typen über alle Schichten hinweg zu teilen. Der größte Vorteil: Ändert sich ein Datenfeld, zeigt der Compiler sofort jede Stelle, die angepasst werden muss. Weil TypeScript-Typen zur Laufzeit verschwinden, brauchen Sie zusätzlich eine Validierung an allen Systemgrenzen.

Warum TypeScript im ganzen Stack sinnvoll ist

TypeScript ist JavaScript mit statischen Typen. Der Code wird vor der Ausführung geprüft und dann zu JavaScript übersetzt. Im Browser läuft React oder ein anderes Frontend-Framework, auf dem Server Node.js, Deno oder Bun. Alle drei Laufzeitumgebungen verstehen JavaScript, und neuere Versionen führen TypeScript-Dateien sogar direkt aus.

Für Unternehmen hat das handfeste Folgen. Ein Team kann an allen Teilen der Anwendung arbeiten, ohne zwischen Sprachen zu wechseln. Datenmodelle werden einmal definiert und überall verwendet. Und viele Fehler, die früher erst beim Kunden auffielen, meldet bereits der Editor.

Die Bausteine eines TypeScript-Stacks

Frontend

React ist im Geschäftsumfeld die verbreitetste Wahl, mit Next.js als Framework für Routing, Server-Rendering und API-Routen. Warum wir uns dafür entschieden haben, erklären wir in Warum Next.js unser Standard-Framework ist. Vue und Svelte unterstützen TypeScript ebenfalls gut.

Backend und API

Das Backend kann Teil der Next.js-Anwendung sein, über Server Actions oder Route Handler. Für größere Systeme bietet sich ein eigener Dienst an, etwa mit Fastify, NestJS oder Hono. Bei der Schnittstelle gibt es zwei verbreitete Wege. Mit tRPC teilen Frontend und Backend die Typen direkt, ohne dass ein Schema gepflegt werden muss. Das passt, wenn beide Seiten im selben Repository leben. Für öffentliche oder von anderen Teams genutzte APIs ist REST mit einer OpenAPI-Beschreibung besser geeignet, aus der sich Client-Typen generieren lassen. Grundlagen dazu finden Sie in unseren Best Practices für API-Design.

Datenbankzugriff

ORMs wie Prisma oder Drizzle erzeugen Typen aus dem Datenbankschema. Wenn Sie eine Spalte umbenennen, schlägt die Typprüfung überall fehl, wo der alte Name noch verwendet wird. Drizzle bleibt dabei nah an SQL, Prisma abstrahiert stärker. Beide arbeiten gut mit PostgreSQL.

Typen zur Laufzeit absichern

Ein häufiges Missverständnis: TypeScript schützt nur den Code, den Sie selbst schreiben. Daten, die von außen kommen, also Formulareingaben, API-Anfragen, Webhooks oder Antworten fremder Dienste, kennt der Compiler nicht. Ein as User behauptet nur etwas, es prüft nichts.

Deshalb gehört an jede Systemgrenze eine Validierung zur Laufzeit. Bibliotheken wie Zod oder Valibot definieren ein Schema, prüfen eingehende Daten dagegen und leiten daraus den TypeScript-Typ ab. So haben Sie eine einzige Quelle für Typ und Prüfung. Dasselbe Schema können Sie im Frontend für die Formularvalidierung und im Backend für die API verwenden.

Projektstruktur und Codequalität

Wenn Frontend, Backend und gemeinsame Pakete wachsen, hilft ein Monorepo. Gemeinsame Typen, Validierungsschemas und UI-Komponenten liegen in eigenen Paketen, die alle Anwendungen importieren. Wie das mit Turborepo funktioniert, beschreiben wir in Monorepos mit Turborepo.

Ein paar Grundregeln sparen viel Ärger:

  • strict in der tsconfig.json von Anfang an aktivieren. Nachträglich ist das mühsam.
  • any vermeiden. Wo ein Typ wirklich unbekannt ist, unknown verwenden und prüfen.
  • Typen aus Schemas ableiten, statt sie doppelt zu pflegen.
  • ESLint mit TypeScript-Regeln und einen Formatierer wie Prettier oder Biome im CI laufen lassen.

Weitere Prinzipien finden Sie in unserem Beitrag zu Clean Code in TypeScript-Projekten.

Tests

Die Typprüfung ersetzt keine Tests, sie macht viele triviale Tests aber überflüssig. Konzentrieren Sie sich auf Geschäftslogik mit Unit-Tests, etwa mit Vitest, und auf wichtige Nutzerabläufe mit End-to-End-Tests in Playwright. Beide Werkzeuge unterstützen TypeScript ohne zusätzliche Konfiguration.

Häufige Fragen (FAQ)

Macht TypeScript die Entwicklung langsamer?

Am Anfang kostet das Schreiben von Typen etwas Zeit. Diese Zeit holen Sie bei Änderungen und Refactorings schnell wieder herein, weil der Compiler betroffene Stellen findet. Bei Projekten, die länger als ein paar Wochen leben, überwiegt der Nutzen deutlich.

Können wir ein bestehendes JavaScript-Projekt umstellen?

Ja, schrittweise. TypeScript kann JavaScript-Dateien mitprüfen, und Sie stellen Datei für Datei um. Beginnen Sie mit den Modulen, die am häufigsten geändert werden, und verschärfen Sie die Compiler-Einstellungen nach und nach.

Ist Node.js für ein Backend leistungsfähig genug?

Für typische Business-Anwendungen mit Datenbankzugriffen und API-Aufrufen ja. Node.js ist auf viele gleichzeitige Ein- und Ausgabeoperationen ausgelegt. Rechenintensive Aufgaben wie Bildverarbeitung oder große Datenanalysen lagert man besser in eigene Dienste oder Worker aus.

Fazit

Der Wert von TypeScript im ganzen Stack liegt in den gemeinsamen Typen und in der Validierung an den Systemgrenzen. Wer beides von Beginn an einplant, bekommt eine Codebasis, die sich auch nach Jahren noch sicher ändern lässt. Wenn Sie eine Webanwendung mit diesem Stack planen, sprechen Sie mit uns über Webentwicklung mit React, Next.js und TypeScript.