Gerar Tipos TypeScript a partir de JSON — do jeito certo
Gerar tipos a partir de uma resposta de exemplo leva segundos. Ter tipos em que você pode confiar exige mais algumas decisões: o que é opcional, o que é nulo, como nomear as coisas e como garantir que a API cumpra o que promete em tempo de execução.
Comece com exemplos reais
Cole uma resposta no conversor JSON para TypeScript e você recebe interfaces para cada objeto aninhado. Porém, um exemplo mostra apenas um formato, então cole um array com vários objetos reais: o conversor os combina e marca como opcionais os campos que faltam em alguns deles.
[
{ "id": 1, "name": "Ada", "email": "ada@example.com", "team": { "id": 7, "name": "Core" } },
{ "id": 2, "name": "Grace", "email": null }
]
interface User {
id: number;
name: string;
email: string | null;
team?: Team;
}
interface Team {
id: number;
name: string;
}
Opcional não é o mesmo que nulo
team?: Team significa que a chave pode estar ausente. email: string | null significa que a chave sempre existe, mas pode valer null. As APIs usam esses casos de forma diferente, e seu código também os verifica de forma diferente ('team' in user versus user.email === null). Por isso, mantenha a distinção em vez de deixar tudo como ?: … | null.
Refine o que o exemplo não consegue mostrar
- Uniões literais: um campo
statusque aparece como"active"virastring. Substitua por'active' | 'paused' | 'deleted', conforme a documentação da API. - Datas chegam como strings ISO. Tipar como
stringe converter na borda da aplicação. Não finja que são objetosDate. - IDs: IDs numéricos grandes (acima de 253) perdem precisão no JavaScript. Por isso, muitas APIs os enviam como strings.
- Arrays vazios viram
unknown[]ouany[]. Defina você mesmo o tipo dos elementos.
Os tipos desaparecem em tempo de execução
O TypeScript verifica o seu código, não os dados. Se a API mudar, o compilador não vai perceber. Valide as respostas na fronteira da aplicação:
- Gere um schema a partir dos mesmos exemplos com JSON para JSON Schema.
- Edite o schema (campos obrigatórios, enums, formatos como
date-time) e teste payloads reais no Validador de JSON Schema. - Valide na sua aplicação com uma biblioteca como o Ajv e gere os tipos a partir do schema (JSON Schema para TypeScript), assim você tem uma única fonte da verdade.
import Ajv from 'ajv';
const ajv = new Ajv();
const validate = ajv.compile(userSchema);
const data = await res.json();
if (!validate(data)) throw new Error('Unexpected API response: ' + ajv.errorsText(validate.errors));
Bibliotecas como Zod ou Valibot fazem o mesmo, com o schema escrito no próprio TypeScript, e inferem o tipo a partir dele.
Nomes e estrutura
Dê ao tipo raiz um nome significativo (User, e não Root), exporte os tipos de um único módulo e prefira interface para formatos de objeto que você talvez precise estender. Antes de tudo, formate e inspecione respostas grandes com o Formatador de JSON para ver quais ramos importam.