JSON-Verarbeitung in TypeScript: Vom einfachen Parsing zur strengen Typisierung
TypeScript, als Erweiterung von JavaScript, erbt alle integrierten Methoden zur Arbeit mit JSON, fügt ihnen aber ein leistungsstarkes Typsystem hinzu. Allerdings gibt der standardmäßige JSON.parse() den Typ any zurück, was die Vorteile der statischen Typisierung zunichtemacht. In diesem Artikel werden wir uns ansehen, wie man JSON in TypeScript sicher und effizient verarbeitet, sowohl mit nativen Möglichkeiten als auch mit spezialisierten Bibliotheken.
Das Problem mit dem standardmäßigen JSON.parse
Betrachten wir ein typisches Szenario:
const jsonString = '{"name":"Alice","age":30}';const user: any = JSON.parse(jsonString); // Typ anyconsole.log(user.name.toUpperCase()); // Laufzeitfehler, wenn name fehltTypeScript warnt Sie nicht, wenn die JSON-Struktur nicht der erwarteten entspricht. Die Lösung ist die Verwendung einer Typbehauptung (Type Assertion) oder, besser noch, einer Validierung zur Laufzeit.
Einfache Typbehauptung (Type Assertion)
Der einfachste Weg ist, den Ergebnistyp explizit anzugeben:
interface User { id: number; name: string; email?: string;}
const raw = '{"id":1,"name":"Bob"}';const user = JSON.parse(raw) as User;console.log(user.name); // TypeScript weiß, dass dies ein string istNachteil: Wenn das JSON andere Felder enthält, tritt der Fehler erst zur Laufzeit auf. Dies ist bei der Arbeit mit externen APIs unsicher.
Rekursive und bedingte Typen für JSON
TypeScript ermöglicht es, jedes JSON durch einen rekursiven Typ zu beschreiben:
type JSONValue = | string | number | boolean | null | JSONValue[] | { [key: string]: JSONValue };
function safeParse(json: string): JSONValue | Error { try { return JSON.parse(json) as JSONValue; } catch (e) { return new Error('Invalid JSON'); }}Dieser Ansatz stellt sicher, dass das Ergebnis immer eine gültige JSON-Struktur ist, prüft aber nicht die spezifische Form.
Die Bibliothek Zod — Schema-Validierung zur Laufzeit
Zod ist die beliebteste Bibliothek für die deklarative Datenvalidierung in TypeScript. Sie ermöglicht es, ein Schema zu beschreiben und daraus automatisch einen Typ abzuleiten.
Installation
npm install zodAnwendungsbeispiel
import { z } from 'zod';
// Schema beschreibenconst UserSchema = z.object({ id: z.number().positive(), name: z.string().min(1), email: z.string().email().optional(), role: z.enum(['admin', 'user']).default('user'),});
// Typ aus Schema ableitentype User = z.infer<typeof UserSchema>;
// Sicheres Parsingconst result = UserSchema.safeParse(JSON.parse(rawJson));
if (result.success) { // result.data hat den Typ User console.log(result.data.name);} else { console.error(result.error.format());}Zod prüft automatisch Typen, Pflichtfelder, Standardwerte und gibt detaillierte Fehler zurück. Dies ist die ideale Wahl für die Verarbeitung von Daten von REST-APIs oder Konfigurationsdateien.
Die Bibliothek io-ts — funktionaler Ansatz
io-ts basiert auf funktionaler Programmierung und der Bibliothek fp-ts. Sie verwendet die Komposition von Codecs zum Dekodieren/Kodieren von Daten.
Beispiel
import * as t from 'io-ts';import { isRight } from 'fp-ts/lib/Either';
const UserCodec = t.type({ id: t.number, name: t.string, tags: t.array(t.string),});
const decoded = UserCodec.decode(JSON.parse(raw));
if (isRight(decoded)) { // decoded.right — typisiertes Objekt console.log(decoded.right.name);} else { // decoded.left — Validierungsfehler console.log(decoded.left);}io-ts ist strenger und mathematisch korrekter, erfordert aber ein Verständnis funktionaler Konzepte (Either, pipe).
Auch in der Bibliothek
Aufgabenwarteschlangen in Java: ExecutorService und ThreadPoolExecutor
Kotlin Standardbibliothek: vollständiger Überblick und Beispiele
Swift-Aufgabenplaner: GCD, OperationQueue und Combine für iOS/macOS