Generare tipi TypeScript da uno Schema
In sintesi: json-schema-to-typescript e quicktype emettono un .d.ts in un comando, ma è un draft: opzionalità, unioni, additionalProperties e date richiedono un passaggio umano.

In sintesi: genera con json-schema-to-typescript o quicktype, poi correggi a mano opzionalità, unioni, additionalProperties e date; mantieni lo Schema come sorgente e i tipi come output, imposto da un passaggio types:check in CI.
Un comando ti dà un file. Non ti dà tipi corretti.
Il one-liner
npx json-schema-to-typescript schema.json > src/types/order.d.ts
Gestisce $ref, allOf, oneOf, anyOf, e converte description in JSDoc. Per la generazione in batch con un banner e uno style scelto, chiama la sua Node API da un piccolo build-types.mjs.
quicktype è l'alternativa, e può anche inferire uno schema da un JSON di esempio:
npx quicktype -s schema schema.json -o order.ts --lang typescript
Quattro cose da correggere dopo
Opzionalità. Qualsiasi cosa fuori da required diventa ?. Ma "sempre presente, può essere null" e "può essere assente" sono contratti diversi:
interface Order {
remark?: string | null; // may be missing
status: string;
}
Se il backend invia sempre remark: null, rimuovi il ? e smetti di far proteggere ogni consumatore contro undefined.
Unioni non discriminate. oneOf di solito diventa A | B, che TypeScript non riesce a restringere senza un campo letterale. Aggiungi una proprietà type fissa a ogni ramo nello Schema.
additionalProperties. Omesso o true a volte produce [k: string]: unknown, a volte any. Il primo è sicuro, il secondo disattiva silenziosamente il controllo dei tipi per l'intero oggetto.
Formati di data. format: "date-time" è una stringa sul filo. Mapparlo a Date significa che devi anche deserializzare, altrimenti il valore a runtime resta una stringa mentre il tipo mente.
Mantieni fissa la direzione
Lo Schema è la sorgente, i tipi sono output. Generare lo Schema da tipi scritti a mano è accettabile solo se la rigenerazione è obbligatoria e imposta in CI — altrimenti entrambi i lati derivano e nessuno sa quale sia autorevole.
Metterlo nella pipeline
"types:gen": "json2ts -i schemas/ -o src/types/generated",
"types:check": "pnpm types:gen && git diff --exit-code src/types/generated"
types:check è la parte che conta: modifica lo Schema senza rigenerare e la CI fallisce.
FAQ
Perché il file generato contiene any?
Di solito deriva dal fatto che additionalProperties è true o omesso, cosa che alcuni generatori mappano a [k: string]: any. Sostituiscilo con unknown o con campi espliciti, perché any disattiva il controllo dei tipi per l'intero oggetto.
Come devo correggere i campi opzionali dopo la generazione?
Qualsiasi cosa fuori da required diventa ?, ma "sempre presente, può essere null" differisce da "può essere assente". Se il backend invia sempre il campo, rimuovi il ?.
La CI deve fallire quando Schema e tipi derivano?
Sì. Uno script types:check che rigenera ed esegue git diff --exit-code fa fallire la build non appena lo Schema cambia senza rigenerazione.