JSON in TypeScript Automatische Generierung von Interfaces aus API-Antworten
Die manuelle Erstellung von TypeScript-Interfaces für jede API-Antwort ist aufwendig und anfällig für Fehler. Lernen Sie, genaue Interfaces aus echten JSON-Daten automatisch zu generieren, und fügen Sie dann Laufzeitvalidierung mit Zod hinzu – denn Typen verschwinden bei Laufzeit und `any` ist keine Lösung.
Sie haben gerade Daten aus einer Drittanbieter-API abgerufen. Die Antwort ist ein dichter JSON-Block – verschachtelte Objekte, Arrays, nullable Felder – und nun müssen Sie herausfinden, wie man sie in TypeScript typisiert. Also öffnen Sie eine neue Datei und beginnen mit der Eingabe interface User { ... }, und 20 Minuten später haben Sie etwas, das wahrscheinlich die tatsächlichen Daten widerspiegelt. Wahrscheinlich.
Es gibt eine bessere Methode. Werkzeuge, die JSON direkt in TypeScript-Interfaces konvertieren, reduzieren diese 20-minütige Aufgabe auf Sekunden. Dieser Artikel erklärt, wie die generierten Typen aussehen, wie man die komplizierten Fälle (Null-Werte, Vereinigungen, tief verschachtelte Strukturen) behandelt und warum Sie generierte Typen mit Zod-Schemata kombinieren sollten, um Formfehler bei Laufzeit zu erkennen – nicht nur bei der Kompilierung.
Warum TypeScript-Interfaces für API-Antworten wichtig sind
Das Wertangebot von TypeScript besteht darin, Fehler vor dem Ausführen des Codes zu erkennen. Ohne typisierte API-Antworten fliegen Sie blind: Zugriff auf Eigenschaften, die möglicherweise nicht existieren, Behandlung von optionalen Werten als erforderlich oder unsichtbare Umwandlung eines Strings "null" in etwas Ungewöhnliches weiter unten.
Stellen Sie sich diese häufige Situation vor:
const user = await fetchUser(id);
console.log(user.address.city); // TypeError at runtime if address is null
Wenn Sie die Antwort richtig typisiert hätten – mit address: Address | null – hätte TypeScript sofort darauf hingewiesen. Der Compiler ist Ihre erste Verteidigungslinie, aber nur wenn Sie ihm etwas zur Verfügung stellen.
Die manuelle Schaffung von Interfaces für jede API ist langweilig und anfällig für Fehler. Sie lesen die Schema falsch, verpassen ein optionales Feld oder kopieren eine veraltete Version. Die automatische Erzeugung von Interfaces aus echtem JSON-Daten entfernt diesen menschlichen Fehler aus der Gleichung.
Was die JSON-zu-TypeScript-Konvertierung erzeugt
Nehmen Sie einen einfachen API-Antwort:
{
"id": 42,
"username": "jsmith",
"email": "j@example.com",
"createdAt": "2024-01-15T10:30:00Z",
"role": "admin",
"profile": {
"bio": "Developer",
"avatar": null
}
}
Fügen Sie das in das JSON zu TypeScript Schnittstellengenerator ein und Sie erhalten:
interface Profile {
bio: string;
avatar: null;
}
interface RootObject {
id: number;
username: string;
email: string;
createdAt: string;
role: string;
profile: Profile;
}
Ein paar Dinge zu beachten:
- Verschachtelte Objekte werden zu eigenen Interfaces —
Profilewird automatisch extrahiert, anstatt eingebettet. - Datumsfelder werden als
stringgetypet – JSON hat keinen Datentyp, daher bleiben ISO-Strings als Strings. Sie müssen sie selbst parsen. avatar: nullwird als Literalnullgetypet – was genau ist, aber unvollständig. Mehr dazu unten.
Behandlung komplizierter Fälle
Null-Optionale Felder
Wenn ein Feld in Ihrem JSON-Beispiel null ist, wird das Werkzeug es als nulltypisiert. In der Praxis wechselt dieses Feld jedoch wahrscheinlich zwischen einem echten Wert und null abhängig von den Daten. Sie möchten diese manuell anpassen:
// Generated
avatar: null;
// What you actually want
avatar: string | null;
Das gleiche gilt für optionale Felder, die in Ihrem Beispiel vorhanden sind – fügen Sie ? zu jeder Eigenschaft hinzu, die in manchen Antworten fehlen könnte.
Arrays
Arrays von Objekten werden sauber behandelt. Gegeben:
{
"posts": [
{ "id": 1, "title": "Hello", "published": true },
{ "id": 2, "title": "World", "published": false }
]
}
Erzeugt das Werkzeug:
interface Post {
id: number;
title: string;
published: boolean;
}
interface RootObject {
posts: Post[];
}
Union-Typen
Wenn Ihre JSON-Beispiele ein Feld mit unterschiedlichen Typen in verschiedenen Datensätzen zeigen – zum Beispiel ein value das eine Zahl oder einen String sein kann – sollten Sie dies als Vereinigung darstellen. Generierte Typen erkennen dies nicht aus einem einzigen Beispiel, daher lohnt es sich, die API-Dokumentation zu überprüfen:
value: string | number;
Tief verschachtelte Objekte
Tief verschachtelte Strukturen sind der Punkt, an dem manuelle Typisierung wirklich zusammenbricht – und wo Generatoren ihre Werte erbringen. Eine Antwort mit drei oder vier verschachtelten Ebenen wird in eine saubere Hierarchie von benannten Interfaces zerlegt, wobei jedes Interface für seine eigene Form verantwortlich ist.
Der Abstand zwischen kompilierten Typen und der tatsächlichen Laufzeit
Hier ist das, was neue TypeScript-Nutzer oft verpassen: Typen verschwinden bei Laufzeit. TypeScript wird in JavaScript kompiliert, und JavaScript hat keine Konzepte von Interfaces. Wenn Ihre API eine Form zurückgibt, die nicht mit Ihrem deklarierten Typ übereinstimmt, wird TypeScript das nicht wissen – und wird Ihnen nicht sagen.
Das macht das gängige Muster von Casts von API-Antworten tatsächlich gefährlich:
const data = await response.json() as User; // No validation, just trust
Dieser Cast sagt TypeScript „Glauben Sie mir, das ist ein User“ – aber TypeScript hat keine Möglichkeit, es zu überprüfen. Wenn die API ihre Form ändert oder ein Fehlerobjekt zurückgibt, bricht Ihr Code bei Laufzeit auf Weisen, die der Compiler nie gewarnt hat.
Die Lösung ist die Laufzeitvalidierung.
Zod für Laufzeitvalidierung
Zod ist eine TypeScript-erste Schema-Validierungsbibliothek. Sie definieren ein Schema einmal, verwenden es, um eingehende Daten zu parsen, und erhalten ein vollständig typisiertes Ergebnis – oder detaillierte Fehlermeldungen, wenn die Form nicht übereinstimmt. Keine Casts, keine Vermutungen.
Mit dem gleichen JSON-Beispiel aus vorher, erzeugt das JSON zu Zod Schema Generator folgendes:
import { z } from "zod";
const ProfileSchema = z.object({
bio: z.string(),
avatar: z.null(),
});
const RootObjectSchema = z.object({
id: z.number(),
username: z.string(),
email: z.string(),
createdAt: z.string(),
role: z.string(),
profile: ProfileSchema,
});
type RootObject = z.infer<typeof RootObjectSchema>;
Achten Sie auf die letzte Zeile: z.infer leitet den TypeScript-Typ direkt aus dem Schema ab. Sie erhalten sowohl Kompilierzeit-Sicherheit als auch Laufzeitvalidierung aus einer einzigen Quelle der Wahrheit.
Die Verwendung davon an der Fetch-Grenze sieht so aus:
const rawData = await response.json();
const user = RootObjectSchema.parse(rawData); // throws if shape is wrong
// Or use safeParse to avoid throwing:
const result = RootObjectSchema.safeParse(rawData);
if (!result.success) {
console.error(result.error.issues);
} else {
console.log(result.data.username); // fully typed
}
Passen Sie das generierte Schema an, um die null-Optionen anzupassen, die das Werkzeug aus einem einzigen Beispiel nicht erkennen kann:
avatar: z.string().nullable(), // was z.null()
bio: z.string().optional(), // if the field might be absent
Interface vs Type: Welche sollten Sie verwenden?
Beide interface und type Aliases können Objektformen in TypeScript darstellen, und für die meisten API-Antworten sind sie austauschbar. Die praktischen Unterschiede:
- Interfaces können erweitert und zusammengefügt werden – nützlich, wenn Sie eine Basis-Typ aus mehreren Dateien erweitern möchten. Die Deklarationsfusion ermöglicht es Ihnen, Felder zu einem Interface, das bereits anderswo definiert ist, hinzuzufügen.
- Type-Aliases sind flexibler – sie können Vereinigungen, Schnittstellen, Tupel und abgebildete Typen darstellen, was Interfaces nicht können.
- Fehlermeldungen sind oft klarer mit Interfaces – TypeScript erweitert Type-Aliases in Fehlermeldungen, was tief verschachtelte Fehler schwerer lesbar machen kann.
Für API-Antwortformen funktioniert entweder. Wählen Sie interface wenn Sie mit Erweiterungen rechnen; verwenden Sie type wenn Sie Vereinigungen oder Schnittstellen benötigen. Konsistenz innerhalb eines Code-Basises ist wichtiger als, welche Sie wählen.
Der praktische Workflow
Hier ist ein Workflow, der Minuten statt einer ganzen Nachmittagsarbeit erfordert:
- Halten Sie eine echte Antwort. Verwenden Sie die Netzwerk-Optionen Ihres Browsers, Postman oder curl, um eine echte API-Antwort zu erfassen. Je vollständiger das Beispiel ist, desto besser sind die generierten Typen.
- Erzeugen Sie das TypeScript-Interface. Fügen Sie das JSON in das JSON zu TypeScript Schnittstellengeneratorein. Kopieren Sie das Ergebnis in Ihr Projekt.
- Erzeugen Sie das Zod-Schema. Fügen Sie das gleiche JSON in das JSON zu Zod Schema Generatorein. Kopieren Sie das Ergebnis ebenfalls in Ihr Projekt.
- Prüfen Sie auf null- und optionalen Feldern. Scannen Sie das generierte Ergebnis auf Felder, die als Literal
nulltypisiert sind oder Felder, die fehlen könnten. Aktualisieren Sie diese aufstring | null,.nullable(), oder.optional()wie nötig. - Validierung an der Fetch-Grenze. Ersetzen Sie jede
as YourTypeCast durchYourSchema.parse()odersafeParse(). Jetzt ist der Typ sicher gewährleistet, nicht nur angenommen.
Das ist der vollständige Prozess – von Roh-JSON bis zu kompilierten Sicherheits- und Laufzeitgarantien in einigen Minuten.
Das könnte Ihnen auch gefallen
Erweiterungen installieren
IO-Tools zu Ihrem Lieblingsbrowser hinzufügen für sofortigen Zugriff und schnellere Suche
恵 Die Anzeigetafel ist eingetroffen!
Anzeigetafel ist eine unterhaltsame Möglichkeit, Ihre Spiele zu verfolgen. Alle Daten werden in Ihrem Browser gespeichert. Weitere Funktionen folgen in Kürze!
Unverzichtbare Tools
Alle Neuheiten
AlleAktualisieren: Unser neuestes Werkzeug was added on Juni 26, 2026
