🛠️Praxis
TypeScript im Alltag: Komponenten typisieren, Daten von APIs beschreiben, fremde Bibliotheken einbinden und bestehendes JavaScript Schritt für Schritt umstellen.
⚛️TypeScript mit React
@types/react.)Props sind einfach ein Objekttyp für den ersten Parameter. Optionale Props bekommen ? und oft einen Standardwert in der Destrukturierung. Falsche oder fehlende Props meldet der Compiler direkt am JSX.
🔌Typen für APIs: aus JSON
Achtung: Ein einzelnes Beispiel verrät nicht alles – Felder, die im Beispiel null sind, bekommen den Typnull. Die erzeugten Typen sind ein Startpunkt, keine Garantie für echte Serverantworten.
const daten: Buch = await antwort.json() ist ein Versprechen, keine Prüfung (json()liefert any). Für Daten von außen: als unknown annehmen und mit einem Type Guard oder einer Validierungsbibliothek prüfen.📜Typen für APIs: aus OpenAPI
{ "components": { "schemas": { "Status": { "type": "string", "enum": [ "verfuegbar", "ausgeliehen", "vorgemerkt" ] }, "Autor": { "type": "object", "required": [ "id", "name" ], "properties": { "id": { "type": "integer" }, "name": { "type": "string" }, "webseite": { "type": [ "string", "null" ], "format": "uri" } } }, "Buch": { "type": "object", "description": "Ein Buch im Bestand", "required": [ "isbn", "titel", "status", "autoren" ], "properties": { "isbn": { "type": "string", "description": "ISBN-13" }, "titel": { "type": "string" }, "status": { "$ref": "#/components/schemas/Status" }, "autoren": { "type": "array", "items": { "$ref": "#/components/schemas/Autor" } }, "erschienen": { "type": "string", "format": "date" }, "seiten": { "type": "integer" }, "schlagworte": { "type": "array", "items": { "type": "string" } } } }, "BuchListe": { "type": "array", "items": { "$ref": "#/components/schemas/Buch" } } } } }
required→ Pflichtfeld, sonst?enum→ Union von Literalen"type": ["string", "null"](OpenAPI 3.1) bzw.nullable(3.0) →| null$ref→ Verweis auf den benannten Typinteger→number(TypeScript kennt keinen Ganzzahltyp)
📘.d.ts und DefinitelyTyped
.d.ts-Datei enthält nur Typen, keinen Code. tsc erzeugt sie mit declaration: true – links der Code, rechts die daraus erzeugte Deklaration.Woher kommen Typen für Pakete?
- Im Paket selbst (Feld
typesbzw.exportsin derpackage.json) – der Normalfall bei modernen Paketen. - DefinitelyTyped: ein Community-Repository mit Typen für Pakete ohne eigene Typen, installierbar als
npm i -D @types/paketname. - Selbst geschrieben: eine eigene
.d.tsmitdeclare module(rechts).
@types/node werden seit 6.0 nicht mehr automatisch geladen – in der tsconfig.jsongehört "types": ["node"] eingetragen (sonst Fehler TS2591 bei process).// Eigene Deklaration für ein JavaScript-Paket ohne Typen (z. B. types/rechner-lib.d.ts) declare module "rechner-lib" { export function addiere(a: number, b: number): number; export const version: string; }
🚚Migration von JavaScript nach TypeScript
1 · Umbenennen, locker starten
Die .js-Datei wird zu .ts – mit strict: false. Gültiges JavaScript ist (fast immer) gültiges TypeScript: 0 Fehler, aber schon jetzt leitet der Compiler Typen ab (warenkorb ist ein Array von Objekten mit name und preis) und die Autovervollständigung funktioniert. In gemischten Projekten erlaubt allowJs, dass .js- und .ts-Dateien nebeneinander leben.
allowJs leben .js- und .ts-Dateien nebeneinander; mitcheckJs prüft der Compiler sogar JavaScript-Dateien (Typen per JSDoc-Kommentar wie /** @param {number} x */). So lässt sich Datei für Datei umstellen.🕳️Häufige Fehler und Stolperfallen
as statt Prüfung
as behauptet nur. Kommt vom Server etwas anderes, knallt es erst zur Laufzeit – der Compiler meldet nichts.
any ist ansteckend
Was aus any kommt, ist wieder any – Tippfehler rutschen durch. JSON.parse liefert any!
Indexzugriff ohne undefined
Standardmäßig ist liste[10] vom Typ des Elements – obwohl das Element fehlen kann.
Object.keys liefert string[]
Wegen der strukturellen Typisierung kann ein Objekt mehr Schlüssel haben als sein Typ – deshalb ist Object.keys bewusst nur string[].
{} heißt nicht „leeres Objekt“
{} bedeutet „irgendein Wert außer null/undefined“ – auch Zahlen und Strings passen. Für „beliebiges Objekt“ nimmt man object oder Record<string, unknown>.
Numerische Enums
Numerische Enums sind lax: Werte werden als Zahlen durchgereicht und im Log steht 1 statt eines lesbaren Namens. Unions von String-Literalen sind lesbarer und löschbar.