JSON Toolkit

Gerando tipos TypeScript a partir de um Schema

Resumo: `json-schema-to-typescript` e quicktype emitem um `.d.ts` em um comando, mas é um rascunho: opcionalidade, unions, additionalProperties e datas precisam de uma passada humana.

Intermediário~4 min de leituraPublicado em 2026-10-30Atualizado em 2026-10-30
Gerando tipos TypeScript a partir de JSON Schema

Resumo da ópera: gere com json-schema-to-typescript ou quicktype e depois corrija à mão opcionalidade, unions, additionalProperties e datas; mantenha o Schema como fonte e os tipos como saída, impondo isso com uma etapa types:check no CI.

Um comando lhe dá um arquivo. Não lhe dá tipos corretos.

O comando único

npx json-schema-to-typescript schema.json > src/types/order.d.ts

Ele trata $ref, allOf, oneOf, anyOf e converte description em JSDoc. Para geração em lote com banner e um style escolhido, chame sua API Node a partir de um pequeno build-types.mjs.

O quicktype é a alternativa, e também consegue inferir um schema a partir de um JSON de amostra:

npx quicktype -s schema schema.json -o order.ts --lang typescript

Quatro coisas a corrigir depois

Opcionalidade. Qualquer coisa fora de required ganha ?. Mas "sempre presente, pode ser null" e "pode estar ausente" são contratos diferentes:

interface Order {
  remark?: string | null;   // pode estar ausente
  status: string;
}

Se o backend sempre envia remark: null, remova o ? e pare de fazer todo consumidor verificar undefined.

Unions sem discriminante. oneOf normalmente vira A | B, que o TypeScript não consegue estreitar sem um campo literal. Adicione uma propriedade type fixa a cada ramo no Schema.

additionalProperties. Omitido ou true às vezes produz [k: string]: unknown, às vezes any. O primeiro é seguro, o segundo desativa silenciosamente a verificação de tipos de todo o objeto.

Formatos de data. format: "date-time" é uma string no fio. Mapeá-lo para Date significa que você também precisa desserializar, ou o valor em tempo de execução continua string enquanto o tipo mente.

Mantenha a direção fixa

Schema é a fonte, tipos são a saída. Gerar o Schema a partir de tipos escritos à mão é aceitável apenas se a regeneração for obrigatória e imposta no CI — caso contrário os dois lados divergem e ninguém sabe qual é autoritativo.

Coloque no pipeline

"types:gen": "json2ts -i schemas/ -o src/types/generated",
"types:check": "pnpm types:gen && git diff --exit-code src/types/generated"

types:check é a parte que importa: mude o Schema sem regenerar e o CI falha.

Perguntas frequentes

Por que o arquivo gerado contém any?

Normalmente vem de additionalProperties ser true ou omitido, que alguns geradores mapeiam para [k: string]: any. Substitua por unknown ou por campos explícitos, porque any desativa a verificação de tipos de todo o objeto.

Como devo corrigir campos opcionais após a geração?

Qualquer coisa fora de required ganha ?, mas "sempre presente, pode ser null" difere de "pode estar ausente". Se o backend sempre envia o campo, remova o ?.

O CI deve falhar quando o Schema e os tipos divergem?

Sim. Um script types:check que regenera e roda git diff --exit-code falha o build assim que o Schema muda sem regeneração.

Leitura adicional