ToolPal
TypeScript-Code auf einem dunklen Bildschirm mit blauem und orangefarbenem Syntaxhervorhebung

Hören Sie auf, TypeScript-Interfaces von Hand zu schreiben: Verwenden Sie einen JSON-Generator

📷 Roman Synkevych / Pexels

Hören Sie auf, TypeScript-Interfaces von Hand zu schreiben: Verwenden Sie einen JSON-Generator

TypeScript-Interfaces manuell aus JSON-Payloads zu schreiben ist mühsam und fehleranfällig. Hier erfahren Sie, wie man es automatisiert und worauf man achten muss.

DVon Daniel Park7. April 20265 Min. Lesezeit

Wenn Sie jemals zwanzig Minuten damit verbracht haben, TypeScript-Interfaces aus einem JSON-Payload, den Sie von einer API erhalten haben, von Hand zu schreiben, wissen Sie bereits, dass es eine jener Aufgaben ist, die wichtig erscheinen, aber fast völlig mechanisch sind. Sie denken nicht. Sie kopieren einfach Feldnamen und inferieren Typen. Das ist die Art von Arbeit, die eine Maschine erledigen sollte.

Und doch tun es viele Entwickler noch von Hand. Dieser Leitfaden erklärt, warum es sich lohnt, damit aufzuhören, was ein JSON-zu-TypeScript-Generator tatsächlich produziert, und — wichtiger — was er nicht kann, damit Sie wissen, wo Sie übernehmen müssen.

Warum TypeScript-Interfaces tatsächlich wichtig sind

Bevor wir zum Tool kommen, lohnt es sich, genau zu verstehen, was Sie von typisierten Interfaces bekommen, über "Bugs finden" hinaus.

IDE-Autovervollständigung ist die unterschätzte Funktion. Wenn Ihre API-Antwort typisiert ist, weiß Ihr Editor genau, welche Felder existieren und welche Form verschachtelte Objekte haben. Sie hören auf zu raten, ob es user.profilePicture oder user.profile_picture oder user.avatar ist.

Refactoring wird viel sicherer. Wenn ein Backend-Team ein Feld von userId in user_id umbenennt, schlägt jede Stelle in Ihrer Codebasis, die auf den alten Namen verweist, zur Kompilierzeit fehl — nicht still zur Laufzeit, nachdem ein Benutzer auf einen Fehler stößt.

Dokumentation, die nicht veraltet. Ein gut benanntes Interface ist oft nützlicher als geschriebene Dokumentation.

Der manuelle Prozess vs. die Verwendung eines Generators

So sieht das manuelle Schreiben von Typen für eine mittelkomplexe API-Antwort aus:

{
  "user": {
    "id": 1042,
    "email": "alice@example.com",
    "name": "Alice Nguyen",
    "roles": ["admin", "editor"],
    "profile": {
      "bio": "Frontend developer based in Berlin.",
      "avatarUrl": "https://cdn.example.com/avatars/1042.png",
      "joinedAt": "2023-06-15T08:30:00Z"
    },
    "settings": {
      "theme": "dark",
      "notifications": {
        "email": true,
        "push": false
      }
    }
  },
  "meta": {
    "requestId": "abc-123",
    "timestamp": 1712486400
  }
}

Fügen Sie dasselbe JSON in das JSON-zu-TypeScript-Tool ein und Sie erhalten dies in unter einer Sekunde:

export interface Root {
  user: User;
  meta: Meta;
}

export interface User {
  id: number;
  email: string;
  name: string;
  roles: string[];
  profile: Profile;
  settings: Settings;
}

export interface Profile {
  bio: string;
  avatarUrl: string;
  joinedAt: string;
}

export interface Settings {
  theme: string;
  notifications: Notifications;
}

export interface Notifications {
  email: boolean;
  push: boolean;
}

export interface Meta {
  requestId: string;
  timestamp: number;
}

Sie müssen nur Root in etwas Sinnvolles wie UserResponse umbenennen.

Reale Anwendungsfälle

API-Antworten typisieren

Das ist der primäre Anwendungsfall. Sie integrieren eine Drittanbieter-API — Zahlungsabwickler, CRM, Wetterdienst — und benötigen Typen für das, was zurückkommt.

Konfigurationsdateien

Wenn Ihre App zur Laufzeit eine JSON-Konfigurationsdatei liest, möchten Sie ein passendes TypeScript-Interface:

// config.interface.ts (generiert aus config.json)
export interface AppConfig {
  database: Database;
  redis: Redis;
  featureFlags: FeatureFlags;
}

export interface Database {
  host: string;
  port: number;
  name: string;
  ssl: boolean;
}

Mock-Testdaten

Beim Schreiben von Tests brauchen Sie oft typisierte Mock-Objekte. Generieren Sie das Interface aus echten Daten, dann erstellen Sie Ihren typisierten Mock dagegen.

Umgang mit kniffligen Fällen

Null-Werte

JSON erlaubt null als Wert, und Generatoren werden diese Felder als null typisieren. In der Praxis bedeutet ein null-Feld aber meist, dass das Feld optional ist:

interface User {
  middleName: string | null;
}

Daten

JSON hat keinen nativen Date-Typ. "2023-06-15T08:30:00Z" ist für JSON ein string. Einige Teams erstellen einen Typ-Alias:

type ISODateString = string;

Diskriminierte Unions

Manchmal gibt eine API abhängig von einem type- oder status-Feld unterschiedliche Formen zurück. Das müssen Sie selbst schreiben:

type ApiResult = SuccessResult | ErrorResult;

interface SuccessResult {
  type: "success";
  data: OrderData;
}

interface ErrorResult {
  type: "error";
  code: string;
  message: string;
}

Best Practices für generierte Typen

Root-Interface sinnvoll benennen

Der Generator wird es Root oder etwas Generisches nennen. Benennen Sie es immer um, bevor Sie committen. UserProfileResponse, CheckoutSessionPayload, ProductListItem.

Typen in dedizierten Dateien aufbewahren

src/
  types/
    api/
      user.types.ts
      order.types.ts
    config.types.ts

Zod für Laufzeit-Validierung

TypeScript-Typen werden zur Laufzeit gelöscht. Wenn Sie Laufzeit-Garantien benötigen, erwägen Sie Zod:

import { z } from "zod";

const UserSchema = z.object({
  id: z.number(),
  email: z.string().email(),
  name: z.string(),
});

type User = z.infer<typeof UserSchema>;

Was der Generator nicht für Sie tun kann

Er kennt Ihre Geschäftslogik nicht. Ein Feld, das als number typisiert ist, könnte in der Praxis immer eine positive ganze Zahl sein.

Er arbeitet mit einem Schnappschuss. Die generierten Typen spiegeln einen Datensatz wider. Echte APIs entwickeln sich weiter.

Er kann nicht zwischen erforderlich und optional unterscheiden. Jedes Feld im Beispiel wird als erforderlich behandelt.

Er behandelt alle Strings als Strings. Ein status-Feld, das nur "pending", "active" oder "cancelled" enthält, wird als string typisiert statt als der präzisere Literal-Union-Typ.

Das sind keine Gründe, das Tool zu meiden — es sind Gründe, die Ausgabe als Entwurf und nicht als fertiges Produkt zu behandeln. Der Generator erledigt 80% der mühsamen Arbeit. Sie übernehmen die 20%, die ein Verständnis der tatsächlichen Semantik der Daten erfordern.

Alles zusammenbringen

Der Workflow, der für die meisten Projekte sinnvoll ist:

  1. Echtes (oder repräsentatives) JSON-Beispiel aus der API, Konfiguration oder anderen Quellen holen
  2. In den JSON-zu-TypeScript-Generator einfügen
  3. Root in etwas Sinnvolles umbenennen
  4. Ausgabe in die passende *.types.ts-Datei kopieren
  5. Jedes Feld überprüfen: optionale Felder mit ? markieren, | null hinzufügen wo nötig, Literal-Strings in Union-Typen umwandeln wo angemessen
  6. Wenn Ihr Quell-JSON minifiziert und schwer lesbar ist, verwenden Sie zuerst den JSON-Formatter, dann Typen generieren
  7. Wenn Sie auch eine YAML-Konfiguration pflegen, hilft der JSON-zu-YAML-Konverter, diese zu synchronisieren

Das Ziel ist, genaue, benannte, organisierte TypeScript-Typen zu haben, ohne Zeit mit reiner mechanischer Transkription zu verbringen. Der Generator erledigt den mechanischen Teil. Sie bringen den Kontext darüber mit, was die Daten tatsächlich bedeuten.

Handgeschriebene Typen sind nicht von Natur aus besser — sie sind nur langsamer und fehleranfälliger. Verwenden Sie das Tool, überprüfen Sie die Ausgabe und investieren Sie Ihre Zeit in die Teile, die wirklich einen Menschen erfordern.

Häufig gestellte Fragen

D

Über den Autor

Daniel Park

Senior frontend engineer based in Seoul. Seven years of experience building web applications at Korean SaaS companies, with a focus on developer tooling, web performance, and privacy-first architecture. Open-source contributor to the JavaScript ecosystem and founder of ToolPal.

Mehr erfahren

Artikel teilen

XLinkedIn

Verwandte Beiträge