Skip to content
Torna al blog
Tutorial

Da JSON a TypeScript: generare interfacce e tipi (guida 2026)

Converti JSON in interfacce TypeScript correttamente: regole di inferenza, interface vs type, campi opzionali e union, ed errori comuni. Provalo gratis online.

11 min di lettura

Da JSON a TypeScript: generare interfacce e tipi (guida 2026)

Il modo più rapido per passare da JSON a TypeScript è incollare il payload in un convertitore da JSON a TypeScript e copiare l’interfaccia generata: nessuna installazione, nessun upload, tutto pronto nel browser. Questo copre il caso “mi servono i tipi adesso”.

Ma generare tipi e generare tipi buoni sono due cose diverse. Un convertitore deve indovinare: questo campo è opzionale o semplicemente assente in un solo campione? Quell’array contiene sempre stringhe, o a volte anche numeri? La stringa con la data dovrebbe diventare un Date? Questa guida ti mostra come funziona davvero l’inferenza, quando scegliere interface invece di type, e i veri errori in cui si incappa trasformando le risposte di API reali in tipi di cui ti puoi fidare.

Come convertire JSON in TypeScript

Convertire JSON in TypeScript richiede tre passaggi:

  1. Incolla il tuo JSON. Inserisci un oggetto, un array o una risposta API grezza nella casella di input. La conversione parte all’istante, interamente lato client.
  2. Regola l’output. Scegli interface o type, imposta un nome radice come User o ApiResponse, attiva o disattiva la parola chiave export e scegli ?: oppure | null per i campi opzionali.
  3. Copia o scarica. Recupera il TypeScript generato con un clic e incollalo direttamente nel tuo codice.

Questo è tutto per il percorso transazionale. Il convertitore da JSON a TypeScript legge l’input, inferisce un albero di tipi e stampa le definizioni sulla destra: niente lascia la pagina. Il resto di questa guida serve a capire ciò che ha prodotto, così puoi correggere i casi che non riesce a indovinare.

Come i tipi JSON corrispondono a TypeScript

Ogni valore JSON ha un corrispettivo in TypeScript. La mappatura è quasi sempre uno a uno:

Valore JSONTipo TypeScript
"text"string
42, 3.14number
true / falseboolean
nullnull
[1, 2, 3]number[]
{ ... }interface o type

Gli oggetti sono dove si concentra il lavoro. Prendi un tipico payload utente REST:

{
  "id": 101,
  "name": "Ada Lovelace",
  "email": "ada@example.com",
  "active": true,
  "roles": ["admin", "user"]
}

Un convertitore produce questa interfaccia TypeScript a partire dal JSON:

export interface User {
  id: number;
  name: string;
  email: string;
  active: boolean;
  roles: string[];
}

Ogni scalare corrisponde al suo tipo primitivo, e l’array roles diventa string[]. Inseriscilo nel tuo client API e ottieni gratis autocompletamento e controlli a tempo di compilazione.

Come il convertitore inferisce i tipi

Il lavoro vero sta nell’algoritmo di inferenza. Quattro regole coprono quasi tutto ciò che gli darai in pasto.

Inferenza strutturale: un’interfaccia con nome per ogni oggetto

Ogni forma di oggetto distinta diventa una propria interfaccia con nome. Gli oggetti annidati non collassano in tipi inline: vengono estratti in definizioni separate e referenziate:

{
  "order": {
    "id": "A-1",
    "total": 42.5,
    "customer": { "name": "Sam", "vip": false }
  }
}
export interface Root {
  order: Order;
}

export interface Order {
  id: string;
  total: number;
  customer: Customer;
}

export interface Customer {
  name: string;
  vip: boolean;
}

Le forme identiche vengono deduplicate, così due campi con la stessa struttura condividono un’unica interfaccia invece di produrre copie.

Unione di array: inferire i campi opzionali

Quando passi un array di oggetti, il convertitore li unisce chiave per chiave. Se una chiave compare in alcuni elementi ma non in altri, viene marcata come opzionale:

{
  "users": [
    { "id": 1, "nick": "x" },
    { "id": 2 }
  ]
}
export interface Root {
  users: User[];
}

export interface User {
  id: number;
  nick?: string;
}

id è presente in ogni elemento, quindi resta obbligatorio. nick manca nel secondo utente, perciò diventa nick?: string. Ecco perché un singolo campione raramente basta: vedi la sezione sugli errori più avanti.

Tipi union per array misti

Gli array non devono per forza essere omogenei. Quando gli elementi hanno tipi diversi, il convertitore li raccoglie in una union:

{
  "tags": ["a", "b"],
  "meta": [1, "two"]
}
export interface Root {
  tags: string[];
  meta: (string | number)[];
}

tags contiene uniformemente stringhe, quindi string[]. meta mescola un numero e una stringa, producendo (string | number)[]. Un array vuoto non può essere inferito affatto e ricade su unknown[]: una scelta onesta, dato che da zero elementi non c’è nulla da imparare.

Opzionale vs null: ?: rispetto a | null

Sembrano simili ma significano cose diverse. Un campo marcato ?: può essere del tutto assente dall’oggetto. Un campo tipizzato | null è sempre presente ma può contenere il valore null:

{ "score": null }
export interface Root {
  score: number | null;
}

Qui score è presente con un null esplicito, quindi è tipizzato number | null: il valore esiste, è solo null. Confrontalo con nick?: string dell’esempio sull’array, dove la chiave può mancare del tutto. Usa ?: quando l’API può omettere la chiave, e | null quando invia la chiave con un valore null. La maggior parte dei convertitori ti permette di controllare come viene reso questo aspetto con un interruttore.

interface vs type: quale usare?

Entrambi possono descrivere la forma di un oggetto. Ecco come decidere:

EsigenzaUsa
Forma di un oggetto semplice da JSONinterface
Union (A | B) o intersezione (A & C)type
Declaration merging / estensione tra fileinterface
Tipi mappati o condizionalitype
Messaggi di errore dell’editor leggermente più pulitiinterface

Per dati provenienti da un oggetto JSON, interface è la scelta convenzionale e produce errori del compilatore un po’ più gradevoli. Nel momento in cui ti serve una union — diciamo un Result che è o un successo o un errore — devi passare a un type, perché le interfacce non possono esprimere union:

type ApiResult =
  | { status: "ok"; data: User }
  | { status: "error"; message: string };

Un buon valore predefinito: genera un’interface per gli oggetti JSON semplici, e converti in un type quando la forma richiede una union o un’intersezione. Il TypeScript Handbook copre i casi limite se vuoi il confronto completo. Quando ti serve un alias json to typescript type invece di un’interfaccia, la maggior parte dei convertitori espone un singolo interruttore per ribaltare l’intero output.

quicktype vs json-to-ts vs strumenti online vs manuale

Non esiste un unico modo migliore per generare tipi TypeScript: dipende da dove risiede il JSON e da quanto spesso cambia.

ApproccioIdeale perCompromesso
quicktypeOutput multi-linguaggio, generare codice di validazione a runtimePiù pesante; produce più output di quanto spesso serva
json-to-ts (libreria)Codegen a build-time integrato in uno script o in una pipelineRichiede configurazione e un toolchain Node
Strumento online basato su browserConversioni occasionali, payload sensibili, zero installazioneIncollaggio manuale ogni volta
Scrivere i tipi a manoOggetti minuscoli, imparare il sistema dei tipiNoioso e soggetto a errori su larga scala

Scegli quicktype quando ti servono tipi in più linguaggi o vuoi che emetta validatori insieme ai tipi. Scegli la libreria json-to-ts quando la conversione fa parte di uno step di build. Per una conversione rapida — soprattutto di un payload che contiene token, ID cliente o qualsiasi cosa che preferiresti non incollare in un servizio remoto — uno strumento da browser vince su privacy e velocità. Il nostro convertitore da JSON a TypeScript gira interamente lato client: il JSON non lascia mai la pagina, e non c’è nulla da installare o aggiornare.

I tipi non sono validazione: il ponte verso i controlli a runtime

Questo manda in confusione molti team, quindi mettiamolo nero su bianco: i tipi TypeScript vengono cancellati a tempo di compilazione e non fanno nulla a runtime. Un’interface User generata non verificherà che una risposta API reale le corrisponda. Se il server invia id come stringa invece che come numero, TypeScript crede tranquillamente alla tua annotazione di tipo mentre i dati reali mentono.

Per generate typescript types e imporli su dati reali, abbina i tipi a un validatore a runtime:

  • zod — definisci uno schema una volta, inferisci da esso il tipo statico e analizza le risposte a runtime.
  • io-ts — validazione basata su codec, popolare nei codebase funzionali.
  • JSON Schema + Ajv — schemi indipendenti dal linguaggio validati a runtime, utili quando il contratto è condiviso tra servizi.

Un pattern comune è generare l’interfaccia per il supporto dell’editor, poi scrivere uno schema zod corrispondente come effettivo controllo di confine:

import { z } from "zod";

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

type User = z.infer<typeof UserSchema>;

// Genera un'eccezione se la risposta reale non corrisponde allo schema.
const user = UserSchema.parse(await res.json());

Se segui la strada dello schema, la nostra guida alla validazione JSON Schema ti accompagna nella scrittura e nell’applicazione degli schemi dall’inizio alla fine.

Errori comuni nel tipizzare il JSON

I tipi generati sono un punto di partenza, non un prodotto finito. Fai attenzione a questi.

snake_case vs camelCase. I convertitori mantengono le chiavi alla lettera. Un payload in stile GitHub con public_repos produce public_repos: number, non publicRepos. Se il tuo codebase preferisce il camelCase, dovrai convivere con i tipi snake_case oppure aggiungere uno strato di mappatura che rinomina i campi in ingresso.

Le stringhe con date restano string. Un campo come "2026-06-01T00:00:00Z" viene tipizzato come string, non Date. È una scelta deliberata: JSON non ha un tipo data, e indovinare male è peggio che essere onesti. La conversione da stringa a Date spetta al tuo strato di parsing, dove ne hai il controllo.

Fuoriuscita di any e unknown. Gli array vuoti diventano unknown[] e le strutture profondamente miste possono degradare in tipi vaghi. Questi non sono bug; sono il convertitore che ammette di non poter inferire da dati insufficienti. Restringili a mano una volta che conosci la forma reale.

Esplosione di annidamenti profondi. Un payload molto annidato genera una lunga catena di piccole interfacce. Di solito va bene ed è più leggibile di un unico, gigantesco tipo inline, ma vale la pena appiattire le forme che non meritano un nome proprio.

La trappola del singolo campione. Questo è il più importante. I campi opzionali possono essere inferiti solo da più elementi di un array: un singolo oggetto non può dire al convertitore quali chiavi sono talvolta assenti. Raccogli prima un array rappresentativo di risposte. Un formattatore JSON torna comodo per incollare e ispezionare più campioni affiancati prima di convertire, e se stai dando in pasto input non standard come JSONC, leggi la nostra guida JSON5 / JSONC: il convertitore ha bisogno di JSON rigorosamente valido.

Domande frequenti

Come converto JSON in un’interfaccia TypeScript?

Incolla il tuo JSON in un convertitore da JSON a TypeScript. Legge l’input nel tuo browser e genera all’istante un’interfaccia TypeScript. Fai clic su Copia per recuperare il risultato: nessun upload, nessun account, nessun plugin da installare.

Devo usare interface o type per i dati JSON?

Usa interface per le forme di oggetti semplici da JSON: è la convenzione e dà errori dell’editor leggermente più chiari. Passa a type quando ti serve una union o un’intersezione, dato che le interfacce non possono esprimerle.

Come vengono gestiti oggetti annidati e array?

Gli oggetti annidati diventano interfacce separate e con nome (un campo address produce un’interfaccia Address). Gli array di oggetti vengono uniti chiave per chiave in un’unica interfaccia dell’elemento; gli array di primitivi diventano array tipizzati come string[].

Come vengono tipizzati i campi opzionali e null?

Una chiave assente da alcuni elementi di un array viene marcata come opzionale (nick?: string). Una chiave sempre presente ma che contiene null viene tipizzata con | null (score: number | null). Le due descrivono situazioni diverse: assente rispetto a presente-ma-null.

I tipi TypeScript validano il JSON a runtime?

No. I tipi TypeScript vengono cancellati a tempo di compilazione e non controllano i dati a runtime. Per validare una risposta API reale, abbina i tipi generati a un validatore a runtime come zod, io-ts o JSON Schema con Ajv.

quicktype vs json-to-ts vs un convertitore online: qual è il migliore?

quicktype è adatto all’output multi-linguaggio e ai validatori a runtime; la libreria json-to-ts è adatta al codegen a build-time; un convertitore online è adatto a conversioni rapide, private e occasionali con zero installazione. Per payload sensibili, uno strumento da browser lato client tiene i dati fuori da qualsiasi server.

Perché le stringhe con date sono tipizzate come string invece che Date?

JSON non ha un tipo data, quindi una data è solo una stringa sul filo. Tipizzarla come string è onesto e stabile; convertirla in Date è una decisione del tuo strato di parsing, dove controlli il formato e la gestione degli errori.

I miei dati JSON sono privati quando uso un convertitore online?

Con uno strumento lato client, sì. La conversione gira interamente nel tuo browser usando JavaScript, perciò il JSON — inclusi token, ID e dati dei clienti — non lascia mai la pagina e non viene mai inviato a un server.

Articoli correlati

Vedi tutti gli articoli