Gerando tipos TypeScript a partir de JSON: um guia prático
Escrever à mão uma interface TypeScript para uma resposta de API com 40 campos é tedioso e propenso a erros. Um typo num nome de campo quebra a segurança de tipos sem nenhum erro de compilação. Gerar a interface a partir de uma amostra JSON real é mais rápido e mais preciso, desde que você entenda onde a inferência precisa adivinhar.
Como funciona a inferência JSON-para-TypeScript
Um gerador percorre a árvore de valores JSON e mapeia cada tipo JavaScript para seu equivalente TypeScript: string continua string, number continua number, boolean continua boolean, null vira null (ou é mesclado numa union), arrays viram T[] onde T é inferido dos elementos, e objetos viram interfaces aninhadas.
{
"id": 42,
"email": "ada@example.com",
"isActive": true,
"roles": ["admin", "editor"],
"profile": {
"displayName": "Ada",
"avatarUrl": null
}
}interface Root {
id: number;
email: string;
isActive: boolean;
roles: string[];
profile: {
displayName: string;
avatarUrl: string | null;
};
}Onde a inferência precisa adivinhar
Campos opcionais vs. sempre presentes: uma única amostra JSON não consegue dizer ao gerador se avatarUrl às vezes está totalmente ausente (o que deveria ser avatarUrl?: string | null) ou sempre presente mas às vezes null. Alimente o gerador com algumas amostras representativas, ou marque manualmente um campo como opcional após a geração, se você sabe que a API o omite em certas condições.
Números que são IDs vs. quantidades: o JSON tem um único tipo numérico, mas o TypeScript não consegue distinguir um ID inteiro de um preço de ponto flutuante sem contexto extra. Alguns geradores oferecem branded types ou unions literais para isso; a maioria apenas emite number e deixa a distinção com você.
Arrays vazios: um array sem elementos ("tags": []) não dá ao gerador nenhuma pista do tipo do elemento, então ele recorre a unknown[] ou any[]. Aponte o gerador para uma amostra em que o array tenha itens, ou anote-o à mão depois.
Unions de literais de string: o gerador vai inferir como string comum um campo status que contém um de "pending" | "active" | "closed", a menos que veja todos os valores possíveis na amostra. Mesmo assim, a maioria dos geradores usa por padrão o tipo string mais amplo, a não ser que você ative a inferência de union literal.
Datas: o JSON não tem tipo de data, então timestamps chegam como strings (ISO 8601) ou números (epoch Unix). Um gerador tipa um campo de data como string ou number, não como Date, e você ainda precisa analisá-lo depois do fetch.
A mesma ideia em outras linguagens
A lógica de inferência (percorrer a árvore, mapear tipos, nomear objetos aninhados) é a mesma para qualquer linguagem-alvo; só a sintaxe de saída muda. Um struct Go recebe o mesmo mapeamento de campos com struct tags para os nomes das chaves JSON; uma dataclass Python recebe type hints e um wrapper Optional[...] quando necessário; uma classe Java ou C# recebe campos tipados e getters/setters ou records. Se seu time trabalha em várias linguagens contra a mesma API, gere os tipos de cada uma a partir da mesma amostra JSON para que fiquem coerentes.
type Root struct {
ID int `json:"id"`
Email string `json:"email"`
IsActive bool `json:"isActive"`
Roles []string `json:"roles"`
Profile struct {
DisplayName string `json:"displayName"`
AvatarURL *string `json:"avatarUrl"`
} `json:"profile"`
}Antes de confiar nos tipos gerados
Trate os tipos gerados como ponto de partida e termine o contrato você mesmo. Antes de fazer commit, confirme os campos opcionais com a documentação da API (uma amostra não basta), troque por unions literais os campos string vagos que guardam enums, verifique se campos de array vazio receberam um tipo de elemento real a partir de uma amostra melhor, e gere de novo sempre que a API upstream adicionar ou renomear um campo, em vez de remendar a interface à mão.
FAQ
- Um gerador JSON-para-TypeScript consegue lidar com um campo que às vezes é string e às vezes é number?
- Sim, se ele vir as duas variantes entre as amostras que você fornece; ele deve inferir string | number. Com uma amostra só, ele consegue tipar apenas o que viu. Por isso vale gerar a partir de vários payloads representativos, e não de um único exemplo de caminho feliz.
- Interfaces geradas devem usar `interface` ou `type`?
- Para este caso eles funcionam quase igual. `interface` é mais comum para formas de objeto e suporta declaration merging; `type` lida melhor com unions e intersections. Os dois servem para formas de resposta de API, então siga a convenção do seu codebase.
- Como manter os tipos gerados em sincronia conforme a API evolui?
- Trate a geração como uma etapa repetível, não um copy-paste único: mantenha uma amostra real de resposta versionada no repositório (ou obtida de um endpoint de staging) e gere a interface novamente sempre que a amostra mudar, em vez de editar à mão o arquivo gerado. Alguns times ligam isso ao CI para capturar desvios automaticamente.
- Isso funciona para JSON profundamente aninhado ou recursivo, como uma estrutura de árvore?
- Aninhamento profundo gera interfaces aninhadas sem problema. Estruturas recursivas (um comentário que contém respostas da mesma forma) precisam de um tipo autorreferencial, e a maioria dos geradores não o infere de uma única amostra. Escreva a interface recursiva à mão uma vez e reutilize.
Experimente estas ferramentas
JSON to TypeScript →
Generate TypeScript interfaces from JSON with optional readonly modifiers and JSDoc comments.
JSON to Go →
Generate Go structs with json tags from a JSON sample, ready for encoding/json.
JSON to Python →
Generate Python TypedDict classes from a JSON sample for mypy, Pyright, and editor autocompletion.
Artigos relacionados
O que é JSON? Um guia completo para iniciantes →
JSON (JavaScript Object Notation) é um formato leve de troca de dados, fácil de ler por humanos e de analisar por máquinas. Aprenda a sintaxe, os tipos de dados e a estrutura que sustentam as APIs modernas.
A história do JSON: de 2000 a padrão da indústria →
Acompanhe o JSON desde a ideia de Douglas Crockford em 2001, passando pela adoção pelo Yahoo, até se tornar o padrão ECMA-404 que sustenta 90% das APIs modernas.
O guia completo do JSON Schema (Draft 7) →
O JSON Schema é o padrão para descrever e validar a estrutura de JSON. Aprenda as palavras-chave essenciais, construa um schema real de API e aplique as melhores práticas.