JSON a TypeScript

Incolla JSON e ottieni all'istante interfacce TypeScript.

Nessun dato lascia il tuo dispositivo

Come usare

  1. Incolla il tuo JSON nel pannello di sinistra (oggetto o array).
  2. Clicca su Converti · le interfacce TypeScript appaiono a destra.
  3. Regola il nome radice e attiva le opzioni in base alle tue esigenze.
  4. Clicca su Copia l'output per copiare il codice generato.

Domande frequenti

Gestisce gli oggetti annidati?

Sì. Ogni oggetto annidato riceve la propria interfaccia con nome. Anche gli elementi degli array vengono analizzati per determinare il tipo di elemento.

Cosa succede con array di tipi misti?

Se un array contiene elementi di tipi diversi, il convertitore usa un tipo unione (per es. string | number).

Supporta gli array JSON alla radice?

Sì. Se il valore radice è un array, il convertitore analizza i suoi elementi e produce l'interfaccia appropriata insieme a un alias di tipo per l'array.

Cosa fa effettivamente il convertitore

Analizza il JSON, percorre ogni valore e genera un insieme di dichiarazioni interface TypeScript che descrivono la struttura. Ogni oggetto nidificato ottiene una propria interface con nome, derivata dalla chiave della proprietà padre in PascalCase (un campo user diventa una User interface). Quando due oggetti nidificati collidono sul nome, al secondo viene aggiunto un suffisso numerico (User, User2). A livello radice, un array diventa un alias type Root = RootItem[]; più la RootItem interface; un oggetto diventa una singola Root interface (o qualunque nome si inserisca nel campo «root name»).

Esempio di input e output:

// Input
{
  "id": 42,
  "name": "Ada",
  "active": true,
  "tags": ["admin", "billing"],
  "profile": { "bio": "Programmer", "link": null }
}

// Output
export interface Root {
  id: number;
  name: string;
  active: boolean;
  tags: string[];
  profile: Profile;
}

export interface Profile {
  bio: string;
  link: unknown;
}

Il mapping dei tipi JSON → TypeScript

Valore JSONTS generato
"hello"string
42 o 3.14number (TS non ha un tipo intero separato)
true / falseboolean
nullunknown (il convertitore non riesce a stabilire se il campo è nullable o semplicemente assente in questo campione)
[]unknown[]
[1, 2, 3]number[]
[1, "x"](number | string)[]
{ "a": 1 }interface denominata

Per gli array di oggetti a livello radice, il convertitore unisce le chiavi di tutti gli elementi in un'unica interface rappresentativa. È un'approssimazione ragionevole quando gli elementi condividono la stessa struttura, ma perde informazioni quando le strutture divergono davvero (ad es. un array di eventi eterogenei). In quel caso, sarà necessario scrivere a mano un'unione discriminata dopo la generazione.

Perché interface per gli oggetti e type per l'array radice

Il TypeScript Handbook ufficiale fornisce un'euristica in una riga: «Se volete un'euristica, usate interface finché non avete bisogno di usare funzionalità di type.» Entrambi sono strutturalmente tipizzati, entrambi possono descrivere strutture di oggetti, ma interface prevale per le strutture degli oggetti perché supporta il declaration merging (riaprire l'interface per aggiungere campi), funziona bene con extends e appare per nome negli errori del compilatore. Gli alias type sono necessari per le unioni di primitivi, le intersezioni di più tipi o per denominare qualcosa che non è un oggetto: ecco perché l'array a livello radice ottiene un alias type Root = RootItem[]; anziché un'interface.

Una nota sulla denominazione: il convertitore usa il PascalCase senza il prefisso I storico (quindi User anziché IUser). Le linee guida di stile TypeScript moderne (quelle di Google, Microsoft e della comunità React) quasi universalmente eliminano il prefisso. I nomi delle proprietà corrispondono esattamente alle chiavi JSON (camelCase se il JSON usa camelCase, snake_case se usa snake_case). Le chiavi che non sono identificatori JS validi (contenenti trattini, spazi o che iniziano con una cifra) vengono messe tra virgolette: "foo-bar": string;.

Cosa non fa questo strumento (ammettere i limiti)

Un singolo esempio JSON contiene meno informazioni di uno schema reale, quindi alcune cose che sarebbe utile rilevare non sono possibili dal solo input:

Quando usare questo strumento

Code-first vs Schema-first vs diretto (dove si colloca questo strumento)

Tre flussi di lavoro comuni per ottenere tipi TypeScript dai dati in runtime:

La scelta giusta dipende dal fatto che la preoccupazione riguardi principalmente la verifica statica dei tipi (questo strumento è ottimo) o anche la sicurezza in runtime (in quel caso usare Zod / Effect Schema).

Errori comuni

  1. Trattare i tipi generati come una specifica definitiva. Sono un punto di partenza completato al 70%. Aggiungere ? per i campi opzionali, | null dove effettivamente nullable, unioni di letterali stringa dove applicabile.
  2. Generare da un singolo esempio quando l'API ha varianti. Un oggetto utente che a volte ha il campo email e a volte no verrà generato con «email obbligatoria». Eseguire su più esempi e unire i risultati, o modificare a mano.
  3. Contrassegnare tutto automaticamente come readonly. Utile per i flussi di dati immutabili, ma errato per gli oggetti di stato che si mutano. Usare il toggle readonly con attenzione.
  4. Fidarsi della precisione per ID interi grandi. Il number di JavaScript arriva al massimo a 253−1. Per ID a 64 bit, trasmettere come stringhe e tipare come string.
  5. Confondere interface con type. Strumenti diversi, compromessi diversi. L'euristica del TypeScript Handbook è «usa interface a meno che non ti serva una funzionalità che solo type offre», esattamente ciò che fa questo strumento.
  6. Incollare JSON riservato in un convertitore lato server. Le risposte API reali contengono spesso dati dei clienti, credenziali, ID interni. La conversione esclusivamente nel browser (questo strumento) mantiene i dati sul proprio dispositivo.

Altre domande frequenti

Perché tutti i miei campi sono stati contrassegnati come obbligatori?

Perché un singolo esempio JSON non riesce a dire al convertitore quali campi sono a volte assenti nella vera API. Ogni chiave che appare nell'esempio diventa obbligatoria. Se si sa che un campo è opzionale, aggiungere un ? finale a mano: email?: string;. Per il rilevamento dell'opzionalità su più campioni, il più sofisticato CLI quicktype lo gestisce nativamente.

Perché il mio campo null è tipato come unknown?

Perché il convertitore non riesce a stabilire da un singolo null se il campo è sempre nullable (string | null) o se era semplicemente null in questo campione (string). unknown è il default conservativo; TypeScript obbligherà a restringere il tipo prima di usare il valore, il che è più sicuro di any. Modificare in string | null a mano una volta nota l'intenzione dell'API.

Devo usare interface o type?

L'euristica del TypeScript Handbook ufficiale: usare interface finché non si ha bisogno di una funzionalità fornita solo da type, principalmente tipi unione, tipi intersezione o la denominazione di un tipo primitivo. Questo convertitore segue quella regola: interface per ogni struttura oggetto, type per l'alias dell'array radice. Alcune linee guida di stile raccomandano di usare type per impostazione predefinita (Matt Pocock ha sostenuto pubblicamente questa tesi), ma il default convenzionale è interface per gli oggetti.

Il mio JSON verrà caricato da qualche parte?

No. La conversione è un IIFE JavaScript autonomo che analizza il JSON tramite JSON.parse, percorre il valore e scrive l'output TypeScript in un'area di testo. Non ci sono fetch, né chiamate di analytics che portano il contenuto JSON, né server. Questo è importante perché le risposte API reali contengono tipicamente dati dei clienti, ID interni o credenziali che non si vogliono far transitare attraverso terze parti.

E JSDoc, Zod o la validazione runtime?

Questo strumento emette solo tipi TypeScript in fase di compilazione: nessun validatore runtime (niente Zod / Yup / Effect Schema), nessun commento JSDoc. Se si ha bisogno di validazione runtime che funzioni anche come tipo statico, scrivere lo schema in Zod e usare z.infer<typeof Schema> di Zod per derivare il tipo. Se si dispone di un JSON Schema e si vogliono sia la validazione runtime sia i tipi TS, json-schema-to-typescript + AJV è l'abbinamento convenzionale.

Perché non c'è il prefisso I nei nomi delle interface?

Perché la maggior parte delle linee guida di stile TypeScript moderne lo elimina. La TypeScript Style Guide di Google ne sconsiglia esplicitamente l'uso; la comunità React ha convergito su PascalCase senza prefisso. La convenzione storica IUser proveniva dall'influenza di C# / Java sul primo TypeScript; la pratica attuale è il semplice User.

Strumenti correlati

Formattatore e validatore JSON gratuito online Convertitore JSON a Go Struct Gratuito Generatore schema JSON