Skip to content
Back to Blog
developerjson-formattertypescriptweb-development

Como Converter JSON para Tipos TypeScript

Colar JSON em um gerador de tipos é fácil; acertar campos opcionais e tipos união não é. Veja como fazer corretamente, além de um conversor gratuito no navegador.

SZ
Founder, Molixa
11 min read
Compartilhar
Como Converter JSON para Tipos TypeScript
Table of contents7 sections

Para converter JSON para TypeScript, mapeie cada valor JSON para seu tipo: strings viram string, números viram number, objetos viram definições de interface aninhadas e arrays viram T[]. As partes difíceis são inferir campos opcionais versus obrigatórios, colapsar arrays mistos em tipos união e decidir quando você também precisa de validação em tempo de execução com Zod.

A geração automática lida com os 90% chatos. Os 10% restantes, a parte que um conversor ingênuo erra, é onde os bugs moram. Uma única amostra de API não pode dizer quais campos são anuláveis, quais às vezes estão ausentes ou se um array vazio é string[] ou never[]. Este guia aborda a mecânica e as pegadinhas, depois mostra como gerar a interface, um esquema Zod e uma struct Go a partir de uma única colagem.

O Mapeamento Básico: Valores JSON para Tipos TypeScript#

Comece com uma resposta de API concreta. Digamos que você está integrando um endpoint de usuário:

{
  "id": 4821,
  "username": "ada",
  "email": "[email protected]",
  "isActive": true,
  "roles": ["admin", "editor"],
  "profile": {
    "displayName": "Ada Lovelace",
    "avatarUrl": null
  },
  "lastLoginAt": "2026-05-30T11:04:00Z"
}

Uma tradução direta e correta fica assim:

interface User {
  id: number;
  username: string;
  email: string;
  isActive: boolean;
  roles: string[];
  profile: Profile;
  lastLoginAt: string;
}

interface Profile {
  displayName: string;
  avatarUrl: string | null;
}

Algumas decisões já estão embutidas aqui que um gerador descuidado perderia. Observe que avatarUrl é string | null, não string, porque o valor de exemplo é null. Observe que lastLoginAt é string, não Date, porque JSON não tem tipo data, é apenas uma string ISO até que você a analise. E profile foi extraído para sua própria interface nomeada Profile em vez de ser inline, o que mantém os tipos reutilizáveis.

A tabela de mapeamento principal é curta:

JSONTypeScriptCuidado com
"texto"stringDatas ISO ainda são string
42, 3.14numberSem distinção int vs float
true / falseboolean
nullnullGeralmente parte de uma união, ex.: string | null
{ ... }interface / objeto aninhadoExtraia formas reutilizadas em interfaces nomeadas
[ ... ]T[]Arrays de tipos mistos viram uma união; arrays vazios são ambíguos

Interface vs Type Alias: Qual Gerar#

Tanto interface quanto type podem descrever a forma de um objeto, e para respostas de API simples elas são quase intercambiáveis. A orientação prática:

  • Use interface para formas de objeto que você possa estender ou que representem um contrato de API. Interfaces suportam mesclagem de declaração e produzem mensagens de erro mais limpas.
  • Use type quando precisar de uniões, interseções, tipos mapeados ou tuplas que uma interface não pode expressar.

Para modelos derivados de JSON, opte por interface. Recorra a type apenas quando os dados forem uma união, como um campo que é "pending" | "complete". A maioria dos geradores permite escolher o estilo de saída, e interface é o padrão mais seguro para uma forma de API externa.

Os Três Problemas que Geradores de Amostra Única Erram#

É aqui que a maioria dos conversores online falha. Eles traduzem exatamente o que você cola e nada mais, então os tipos são tão corretos quanto sua única amostra.

Problema 1: Campos opcionais vs obrigatórios#

Uma resposta não pode dizer se um campo é opcional. Se avatarUrl está presente na sua amostra, mas a API o omite para usuários que nunca definiram um, um gerador marca como obrigatório e seu código quebra em tempo de execução quando ele está ausente.

Você tem duas opções honestas. Ou alimente o gerador com várias amostras para que ele veja quais chaves desaparecem, ou marque campos como opcionais manualmente com base na documentação da API:

interface User {
  id: number;
  username: string;
  email: string;
  isActive: boolean;
  roles: string[];
  profile: Profile;
  lastLoginAt?: string; // opcional: ausente para usuários que nunca fizeram login
}

O ? torna a propriedade string | undefined. Isso é diferente de string | null. null significa que a chave está presente com valor nulo; undefined significa que a chave pode estar totalmente ausente. Confundir os dois é uma fonte clássica de erros cannot read property of undefined.

Problema 2: Tipos união de arrays mistos#

Arrays reais nem sempre são homogêneos. Considere um feed de eventos:

{
  "events": [
    { "type": "click", "x": 120, "y": 44 },
    { "type": "scroll", "delta": -300 }
  ]
}

Um gerador fraco ou pega a forma do primeiro elemento e ignora o resto, ou mescla todos os campos em um objeto inchado com tudo opcional. A saída correta é uma união discriminada:

type AppEvent =
  | { type: "click"; x: number; y: number }
  | { type: "scroll"; delta: number };

interface EventPayload {
  events: AppEvent[];
}

O campo type compartilhado é o discriminante. TypeScript agora pode restringir a união em um switch (event.type), o que uma única interface mesclada nunca permitiria.

Problema 3: Arrays vazios e campos apenas nulos#

Qual é o tipo de "tags": []? Não há elemento para inferir, então a resposta honesta é "desconhecido." Ferramentas ingênuas emitem any[] ou never[], ambos errados na prática. O mesmo problema atinge um campo cujo único valor de amostra é null: você não pode saber o tipo não nulo apenas a partir de null. Quando encontrar isso, forneça uma amostra com dados ou anote o tipo você mesmo (tags: string[]) com base no que sabe que a API retorna.

Quando Você Também Precisa de Zod (Validação em Tempo de Execução)#

Os tipos do TypeScript desaparecem em tempo de compilação. Eles não oferecem nenhuma proteção contra uma API que retorna algo diferente do que você tipou. Se o servidor enviar uma string onde você esperava um número, o TypeScript já confiou na forma errada e seu aplicativo falha com um erro confuso.

Zod preenche essa lacuna. Você define um esquema uma vez, valida a resposta na fronteira e infere o tipo estático a partir do mesmo esquema, sem precisar escrever duas vezes:

import { z } from "zod";

const ProfileSchema = z.object({
  displayName: z.string(),
  avatarUrl: z.string().url().nullable(),
});

const UserSchema = z.object({
  id: z.number().int(),
  username: z.string(),
  email: z.string().email(),
  isActive: z.boolean(),
  roles: z.array(z.string()),
  profile: ProfileSchema,
  lastLoginAt: z.string().datetime().optional(),
});

// O tipo estático é derivado do esquema, não escrito à mão:
type User = z.infer<typeof UserSchema>;

// Na fronteira da rede:
const user = UserSchema.parse(await response.json());

Agora UserSchema.parse() lança um erro preciso e legível no momento em que os dados violam o contrato, e z.infer mantém o tipo TypeScript perfeitamente sincronizado. Use Zod (ou uma alternativa como Valibot) sempre que os dados cruzarem uma fronteira de confiança: respostas HTTP, entrada de formulários, webhooks, filas de mensagens, qualquer coisa que você não produziu. Para dados internos totalmente tipados que você controla do início ao fim, interfaces simples são suficientes.

Regra prática: se o JSON vier de fora do seu código, valide-o em tempo de execução. Tipos sozinhos são uma promessa, não uma garantia.

Precisa de um Struct em Go?#

Equipes de backend frequentemente precisam da mesma estrutura em Go. O mapeamento espelha o TypeScript, com tags de struct carregando os nomes das chaves JSON:

type Profile struct {
	DisplayName string  `json:"displayName"`
	AvatarURL   *string `json:"avatarUrl"`
}

type User struct {
	ID          int      `json:"id"`
	Username    string   `json:"username"`
	Email       string   `json:"email"`
	IsActive    bool     `json:"isActive"`
	Roles       []string `json:"roles"`
	Profile     Profile  `json:"profile"`
	LastLoginAt string   `json:"lastLoginAt"`
}

Observe o ponteiro *string para avatarUrl: em Go, um ponteiro é como você representa um campo anulável, já que o valor zero de string é "", não nil. A mesma questão de anulabilidade do lado do TypeScript ressurge aqui em uma forma diferente.

Gere sem colar em um site aleatório#

Fazer isso manualmente para um payload grande é tedioso e sujeito a erros, mas colar JSON de produção, que pode conter tokens, e-mails ou dados de clientes, em um serviço remoto desconhecido é pior. Um conversor que respeita a privacidade faz a transformação inteiramente no seu navegador, para que os dados nunca toquem um servidor.

Passo 1: Cole e valide o JSON#

Cole sua resposta de API em um formatador e conversor JSON gratuito. Ele primeiro valida o JSON e o formata de forma legível, para que você detecte uma vírgula sobrando ou uma chave sem aspas antes mesmo de pensar em tipos. JSON malformado é a razão mais comum para uma conversão produzir lixo silenciosamente.

Passo 2: Escolha seu destino de saída#

Escolha o formato necessário: uma interface TypeScript, um esquema Zod ou uma struct Go. Como o conversor de JSON para TypeScript roda no lado do cliente, você pode enviar com segurança respostas reais e não editadas sem se preocupar com o destino dos dados. Toda a transformação acontece na aba.

Passo 3: Refine campos opcionais e uniões manualmente#

A geração fornece um esqueleto correto a partir da amostra. Agora aplique os três pontos de atenção: marque chaves genuinamente opcionais com ?, amplie campos com apenas null ou arrays vazios para seus tipos reais e converta arrays de objetos mistos em uniões discriminadas. Esses últimos 10% exigem julgamento que a ferramenta não pode fazer a partir de um único payload, e é o que separa tipos que compilam de tipos que realmente correspondem à API.

Quando seu fluxo de trabalho envolve mais do que tipos, o mesmo kit de ferramentas ajuda: valide tokens com as ferramentas adjacentes ao decodificador JWT, teste padrões de extração no testador de regex ou manipule payloads codificados com o codificador e decodificador Base64. Para um olhar mais aprofundado sobre fluxos de trabalho JSON do dia a dia, veja nosso guia sobre por que um formatador JSON é uma ferramenta diária para desenvolvedores.

Perguntas Frequentes#

Como converter JSON para uma interface TypeScript? Mapeie cada valor JSON para seu equivalente em TypeScript: strings para string, números para number, objetos para interfaces aninhadas e arrays para T[]. Extraia formas de objetos reutilizadas em interfaces nomeadas. O caminho mais rápido e confiável é colar o JSON em um conversor e, em seguida, corrigir manualmente campos opcionais, uniões nulas e arrays mistos que a amostra não pôde revelar.

Devo usar uma interface ou um alias de tipo para dados JSON? Use interface por padrão para formas de objetos de uma API, já que interfaces se estendem de forma limpa e fornecem mensagens de erro mais claras. Use um alias type quando os dados forem uma união, interseção ou tupla que uma interface não pode expressar, como um campo de status que é "pending" | "complete".

Como lidar com campos opcionais ao gerar tipos a partir de JSON? Uma única amostra não pode revelar campos opcionais, então um gerador marca tudo como obrigatório. Alimente-o com várias respostas para que ele veja quais chaves desaparecem, ou adicione o modificador ? manualmente com base na documentação da API. Lembre-se de que field?: string (pode estar ausente) difere de field: string | null (presente mas nulo).

Preciso de Zod se já tenho tipos TypeScript? Sim, sempre que os dados cruzarem um limite de confiança. Os tipos TypeScript são apagados em tempo de compilação e não podem validar o que uma API realmente retorna em tempo de execução. O Zod valida a carga real e permite inferir o tipo estático a partir do mesmo esquema com z.infer, para que o tipo e a verificação em tempo de execução nunca se distanciem.

É seguro converter JSON para TypeScript online? Apenas se o conversor for executado no seu navegador. Muitas ferramentas online enviam seu JSON colado para um servidor, o que é arriscado quando a carga contém tokens, e-mails ou dados de clientes. Um conversor do lado do cliente, como o formatador JSON Molixa, realiza toda a transformação localmente, de modo que os dados nunca saem da sua aba.

Como converter objetos JSON aninhados para TypeScript? Extraia cada objeto aninhado em sua própria interface nomeada e faça referência a ela a partir do pai, em vez de embutir tudo profundamente. Para o exemplo de usuário, profile se torna uma interface Profile separada que User referencia. Interfaces nomeadas são reutilizáveis, produzem mensagens de erro mais curtas e tornam os tipos gerados muito mais fáceis de ler.

developerjson-formattertypescriptweb-development

More from Molixa

Try Molixa Tools

50+ free AI tools for content creation, SEO, coding, and more. No signup, no watermark.

Explore all tools