JSON para TypeScript

Cole JSON e obtenha instantaneamente interfaces TypeScript.

Nenhum dado sai do seu dispositivo

Como usar

  1. Cole seu JSON no painel da esquerda (objeto ou array).
  2. Clique em Converter · as interfaces TypeScript aparecem à direita.
  3. Ajuste o nome raiz e ative as opções conforme necessário.
  4. Clique em Copiar a saída para copiar o código gerado.

Perguntas frequentes

Ele lida com objetos aninhados ?

Sim. Cada objeto aninhado recebe sua própria interface nomeada. Os elementos dos arrays também são analisados para determinar o tipo de elemento.

O que acontece com arrays de tipos mistos ?

Se um array contém elementos de tipos diferentes, o conversor usa um tipo union (por ex. string | number).

Ele suporta arrays JSON na raiz ?

Sim. Se o valor raiz é um array, o conversor analisa seus elementos e produz a interface apropriada e um alias de tipo para o array.

O que o conversor realmente faz

Ele analisa o seu JSON, percorre cada valor e gera um conjunto de declarações interface do TypeScript que descrevem o formato. Cada objeto aninhado recebe a sua própria interface nomeada, derivada da chave da propriedade pai em PascalCase (um campo user vira uma interface User). Quando dois objetos aninhados colidem no nome, o segundo recebe um sufixo numérico (User, User2). Na raiz, um array vira um alias type Root = RootItem[]; mais a interface RootItem; um objeto vira uma única interface Root (ou o nome que você puser no campo «nome raiz»).

Exemplo de entrada e saída:

// Input
{
  "id": 42,
  "name": "Ada",
  "active": true,
  "tags": ["admin", "billing"],
  "profile": { "bio": "Programmer", "link": null }
}

// Output
export interface Root {
  id: number;
  name: string;
  active: boolean;
  tags: string[];
  profile: Profile;
}

export interface Profile {
  bio: string;
  link: unknown;
}

O mapeamento de tipos JSON → TypeScript

Valor JSONTS gerado
"hello"string
42 ou 3.14number (o TS não tem um tipo inteiro separado)
true / falseboolean
nullunknown (o conversor não tem como saber se o campo é anulável ou apenas ausente neste exemplo)
[]unknown[]
[1, 2, 3]number[]
[1, "x"](number | string)[]
{ "a": 1 }interface nomeada

Para arrays de objetos no nível raiz, o conversor mescla as chaves de todos os itens em uma única interface representativa. É uma aproximação razoável quando os itens compartilham um formato, mas perde informação quando os formatos realmente divergem (por exemplo, um array heterogêneo de eventos). Nesse caso, você precisaria escrever uma união discriminada à mão após a geração.

Por que interface para objetos e type para o array raiz

O TypeScript Handbook oficial dá uma heurística de uma linha: «Se você quiser uma heurística, use interface até precisar de recursos do type.» Ambos são tipados estruturalmente, ambos podem descrever formatos de objeto, mas interface vence para formatos de objeto porque suporta a fusão de declarações (reabrir a interface para adicionar campos), funciona de forma limpa com extends e aparece pelo nome nos erros do compilador. Os aliases type são necessários quando você precisa de uniões de primitivos, interseções de múltiplos tipos, ou nomear algo que não é um objeto, e é por isso que o array de nível raiz recebe um alias type Root = RootItem[]; em vez de uma interface.

Uma observação sobre nomenclatura: o conversor usa PascalCase sem o prefixo legado I (ou seja, User em vez de IUser). Os guias de estilo modernos de TS (o do Google, o da Microsoft, o da comunidade React) quase universalmente abandonam o prefixo. Os nomes das propriedades correspondem exatamente às chaves do JSON (camelCase se o JSON usa camelCase, snake_case se usa snake_case). As chaves que não são identificadores JS válidos (com hifens, espaços ou começando com um dígito) ficam entre aspas: "foo-bar": string;.

O que esta ferramenta não faz (sejamos honestos sobre os limites)

Um único exemplo de JSON carrega menos informação do que um schema de verdade, então várias coisas que seria bom detectar não são possíveis só a partir da entrada:

Quando usar esta ferramenta

Code-first vs. schema-first vs. direto (onde esta ferramenta se encaixa)

Três fluxos de trabalho comuns para obter tipos TypeScript a partir de dados em tempo de execução:

A escolha certa depende de se a sua preocupação é principalmente a verificação estática de tipos (esta ferramenta é ótima) ou também a segurança em tempo de execução (nesse caso, recorra ao Zod / Effect Schema).

Erros comuns

  1. Tratar os tipos gerados como uma especificação acabada. Eles são um ponto de partida 70% pronto. Adicione ? para campos opcionais, | null onde for genuinamente anulável, e uniões de literais de string onde for aplicável.
  2. Gerar a partir de um único exemplo quando a API tem variantes. Um objeto de usuário que às vezes tem um email e às vezes não vai gerar como «email obrigatório». Rode vários exemplos e una os resultados, ou edite à mão.
  3. Marcar tudo como readonly automaticamente. Útil para fluxos de dados imutáveis, mas errado para objetos de estado que você modifica. Use o botão readonly com critério.
  4. Confiar na precisão de IDs inteiros grandes. O number do JavaScript chega ao máximo em 253−1. Para IDs de 64 bits, transmita como strings e tipe como string.
  5. Confundir interface com type. Ferramentas diferentes, compensações diferentes. A heurística do TypeScript Handbook é «use interface a menos que você precise de um recurso que só type oferece», exatamente o que esta ferramenta faz.
  6. Colar JSON confidencial em um conversor do lado do servidor. Respostas reais de API costumam conter dados de clientes, credenciais e IDs internos. A conversão só no navegador (esta ferramenta) mantém os dados na sua máquina.

Mais perguntas frequentes

Por que todos os meus campos foram marcados como obrigatórios?

Porque um único exemplo de JSON não tem como dizer ao conversor quais campos às vezes estão ausentes na API real. Toda chave que aparece no exemplo vira obrigatória. Se você sabe que um campo é opcional, adicione um ? ao final à mão: email?: string;. Para a detecção de opcionalidade a partir de várias amostras, a CLI quicktype, mais sofisticada, lida com isso nativamente.

Por que o meu campo nulo está tipado como unknown?

Porque o conversor não tem como saber, a partir de um único null, se o campo é sempre anulável (string | null) ou se apenas calhou de ser null neste exemplo (string). unknown é o padrão conservador; o TypeScript vai obrigar você a estreitar o tipo antes de usar o valor, o que é mais seguro do que any. Edite para string | null à mão assim que souber a intenção da API.

Devo usar interface ou type?

A heurística do TypeScript Handbook oficial: use interface até precisar de um recurso que só type oferece, principalmente tipos de união, tipos de interseção ou nomear um primitivo. Este conversor segue essa regra: interface para todo formato de objeto, type para o alias do array raiz. Alguns guias de estilo recomendam usar type por padrão (Matt Pocock defendeu publicamente essa posição), mas o padrão convencional é interface para objetos.

O meu JSON será enviado para algum lugar?

Não. A conversão é uma IIFE de JavaScript autocontida que analisa o seu JSON via JSON.parse, percorre o valor e escreve a saída TypeScript em uma textarea. Não há fetch, nenhuma chamada de analytics carregando o conteúdo do JSON, nenhum servidor. Isso importa porque respostas reais de API normalmente contêm dados de clientes, IDs internos ou credenciais que você não quer que passem por terceiros.

E quanto a JSDoc, Zod ou validação em tempo de execução?

Esta ferramenta emite apenas tipos TypeScript de tempo de compilação: nenhum validador de tempo de execução (nada de Zod / Yup / Effect Schema), nenhum comentário JSDoc. Se você precisa de validação em tempo de execução que sirva também como tipo estático, escreva o schema em Zod e use o z.infer<typeof Schema> do Zod para derivar o tipo. Se você tem um JSON Schema e quer tanto a validação em tempo de execução quanto os tipos TS, json-schema-to-typescript + AJV é a combinação convencional.

Por que não há um prefixo I nos nomes das interfaces?

Porque a maioria dos guias de estilo modernos de TypeScript o abandona. O TypeScript Style Guide do Google recomenda explicitamente não usá-lo; a comunidade React convergiu para PascalCase sem prefixo. A convenção legada IUser veio da influência de C# / Java no início do TypeScript; a prática atual é simplesmente User.

Ferramentas relacionadas

Formatador e validador JSON gratuito on-line JSON para Go Gerador de esquema JSON