kleine overview von Claude über typescript
+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).
|
||||||
Reference in New Issue
Block a user