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