Keine Werbung mögen? Gehen Werbefrei Heute

JSON in TypeScript Automatische Generierung von Interfaces aus API-Antworten

Aktualisiert am

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.

JSON in TypeScript: Automatisch Generierung von Interfaces aus API-Antworten 1
ANZEIGE Entfernen?

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 InterfacesProfile wird automatisch extrahiert, anstatt eingebettet.
  • Datumsfelder werden als string getypet – JSON hat keinen Datentyp, daher bleiben ISO-Strings als Strings. Sie müssen sie selbst parsen.
  • avatar: null wird als Literal null getypet – 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:

  1. 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.
  2. Erzeugen Sie das TypeScript-Interface. Fügen Sie das JSON in das JSON zu TypeScript Schnittstellengeneratorein. Kopieren Sie das Ergebnis in Ihr Projekt.
  3. 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.
  4. Prüfen Sie auf null- und optionalen Feldern. Scannen Sie das generierte Ergebnis auf Felder, die als Literal null typisiert sind oder Felder, die fehlen könnten. Aktualisieren Sie diese auf string | null, .nullable(), oder .optional() wie nötig.
  5. Validierung an der Fetch-Grenze. Ersetzen Sie jede as YourType Cast durch YourSchema.parse() oder safeParse(). 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.

Möchten Sie werbefrei genießen? Werde noch heute werbefrei

Erweiterungen installieren

IO-Tools zu Ihrem Lieblingsbrowser hinzufügen für sofortigen Zugriff und schnellere Suche

Zu Chrome-Erweiterung Zu Kantenerweiterung Zu Firefox-Erweiterung Zu Opera-Erweiterung

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!

ANZEIGE Entfernen?
ANZEIGE Entfernen?
ANZEIGE Entfernen?

Nachrichtenecke mit technischen Highlights

Beteiligen Sie sich

Helfen Sie uns, weiterhin wertvolle kostenlose Tools bereitzustellen

Kauf mir einen Kaffee
ANZEIGE Entfernen?