Table of Contents
TypeScript
Dieses Projekt wird schrittweise von JavaScript nach TypeScript migriert. JS- und TS-Dateien existieren nebeneinander und können sich gegenseitig importieren.
Voraussetzungen
- Node.js ≥ 22.18 (oder ≥ 23.6), lokal und im Dockerfile.
Node führt
.ts-Dateien direkt aus, indem es die Typannotationen entfernt („Type Stripping“). Es gibt keinen Build-Schritt. typescriptund@types/nodeals Dev-Dependencies.
Beim Start kann je nach Node-Version eine ExperimentalWarning zum Type Stripping
erscheinen. Diese ist harmlos.
Commands
| Command | Zweck |
|---|---|
npx tsc |
Prüft das ganze Projekt auf Typfehler (erzeugt keine Dateien) |
npx tsc -p tsconfig.check.json |
Prüft nur die in dieser Config angegebenen Dateien |
node server.js |
Startet die App wie bisher, .ts-Dateien werden automatisch geladen |
node --version |
Prüfen, ob die Node-Version Type Stripping unterstützt |
Achtung: npx tsc datei.ts ignoriert die tsconfig.json (also auch strict).
Für einzelne Dateien stattdessen eine separate Config verwenden:
{
"extends": "./tsconfig.json",
"include": ["src/config.ts"]
}
tsconfig.json
{
"compilerOptions": {
"target": "ES2022",
"lib": ["ES2022"],
"module": "NodeNext",
"moduleResolution": "NodeNext",
"allowJs": true,
"checkJs": false,
"noEmit": true,
"strict": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"types": ["node"],
"allowImportingTsExtensions": true,
"erasableSyntaxOnly": true,
"verbatimModuleSyntax": true
},
"include": ["**/*.js", "**/*.ts"],
"exclude": ["node_modules", "public"]
}
Wichtige Optionen
noEmit: TypeScript prüft nur, es erzeugt keine.js-Dateien.allowJs: JS-Dateien dürfen TS-Dateien importieren und umgekehrt.checkJs: false: JS-Dateien werden nicht geprüft. Sonst entstehen tausende Fehler, weil JS-Code keine Typinformationen hat.strict: Strenge Prüfung für alle.ts-Dateien (u. a. keine implizitenany, Null-Checks).allowImportingTsExtensions: Erlaubt Imports mit.ts-Endung (nötig für Node).erasableSyntaxOnly: Verbietet TS-Features, die Node nicht einfach entfernen kann (siehe unten).verbatimModuleSyntax: Reine Typ-Imports müssen mitimport typemarkiert werden.
Regeln für TS-Dateien
Imports immer mit Dateiendung
// richtig
import { createConfig } from "./config.ts";
// falsch – Node findet die Datei nicht
import { createConfig } from "./config.js";
import { createConfig } from "./config";
Typ-Imports kennzeichnen
import type { Config } from "./config.ts";
Erlaubt / nicht erlaubt
Erlaubt sind Typannotationen, interface, type, Generics und as-Casts.
Nicht erlaubt (funktioniert nicht mit Type Stripping):
enum, namespace, Parameter Properties im Konstruktor
(constructor(private x: string)). Stattdessen Union Types bzw. normale Klassenfelder verwenden.
unknown statt any
any schaltet die Typprüfung ab. Für Werte unbekannten Typs unknown verwenden,
dann erzwingt TypeScript eine Prüfung oder Umwandlung (z. B. String(value)).
Dokumentation mit TSDoc
/**
* Wandelt einen Wert in eine Ganzzahl um.
*
* @param value - Der umzuwandelnde Wert.
* @param fallback - Rückgabewert, falls das Parsen fehlschlägt.
* @returns Die Ganzzahl oder `fallback`.
*/
Bei @param keine Typen in {} angeben, die stehen bereits in der Signatur.
Einzelne JS-Dateien prüfen
Soll eine JS-Datei trotz checkJs: false geprüft werden, ganz oben einfügen:
// @ts-check
Migrationsstrategie
- Eine Datei nach der anderen migrieren, beginnend mit Dateien, die wenig andere Dateien importieren.
.jsin.tsumbenennen, Typen ergänzen, alte Datei löschen.- Alle Imports der Datei auf die
.ts-Endung anpassen. npx tscausführen, bis keine Fehler mehr kommen.- Tests laufen lassen.
Große Dateien (repositories.js, chatService.js) sowie Tests und
Frontend-Code (public/js) vorerst in JS belassen.
Bereits migriert
src/config.ts
- Exportiert das Interface
Configund den TypTrustProxyValue. createConfig(overrides: Partial<Config>):Partialmacht alle Felder optional, es müssen nur die zu überschreibenden Werte angegeben werden.- Umbenennung:
modelRequestYTimeoutMs→modelRequestTimeoutMs(Tippfehler im alten Code).