kleine overview von Claude über typescript

2026-09-23 20:53:32 +02:00
parent b17935f94b
commit a03acea76d
+147
@@ -0,0 +1,147 @@
# 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**.
- `typescript` und `@types/node` als 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:
```json
{
"extends": "./tsconfig.json",
"include": ["src/config.ts"]
}
```
## tsconfig.json
```jsonc
{
"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 impliziten `any`,
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 mit `import type` markiert werden.
## Regeln für TS-Dateien
### Imports immer mit Dateiendung
```js
// richtig
import { createConfig } from "./config.ts";
// falsch – Node findet die Datei nicht
import { createConfig } from "./config.js";
import { createConfig } from "./config";
```
### Typ-Imports kennzeichnen
```ts
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
```ts
/**
* 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:
```js
// @ts-check
```
## Migrationsstrategie
1. Eine Datei nach der anderen migrieren, beginnend mit Dateien, die wenig
andere Dateien importieren.
2. `.js` in `.ts` umbenennen, Typen ergänzen, alte Datei löschen.
3. Alle Imports der Datei auf die `.ts`-Endung anpassen.
4. `npx tsc` ausführen, bis keine Fehler mehr kommen.
5. 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 `Config` und den Typ `TrustProxyValue`.
- `createConfig(overrides: Partial<Config>)`: `Partial` macht alle Felder optional,
es müssen nur die zu überschreibenden Werte angegeben werden.
- **Umbenennung:** `modelRequestYTimeoutMs` → `modelRequestTimeoutMs`
(Tippfehler im alten Code).