BrowserTools
Início / Conversores / JSON para TypeScript

JSON para TypeScript

Cola um exemplo dos teus dados JSON e obtém os tipos TypeScript que os descrevem.

A carregar JSON para TypeScript… Se nada acontecer, ativa o JavaScript.

Escrever à mão os tipos TypeScript de uma resposta de API é lento e fácil de errar, sobretudo quando o conteúdo é profundo ou alguns campos só aparecem de vez em quando. Cola um exemplo real de JSON nesta ferramenta e ela deduz os tipos por ti enquanto escreves. Cada objeto aninhado passa a ter a sua própria interface com nome, tirado da chave onde está e convertido para PascalCase: uma chave address dá uma interface Address e um array projects dá uma interface Project para os seus elementos. Objetos com exatamente a mesma forma são declarados uma só vez e reutilizados, e nomes que colidiriam entre si ou com tipos incorporados como Date, Response ou Location recebem um sufixo, para que o resultado compile tal como está.

Perguntas frequentes

Como é que os objetos aninhados passam a interfaces?
Cada objeto com pelo menos uma chave passa a ser uma interface separada com nome. O nome vem da chave que o contém, convertida para PascalCase: billing_address dá BillingAddress. Os elementos de um array recebem a forma no singular da chave, por isso orders dá Order e categories dá Category. O objeto raiz usa o nome que escreves na caixa Root name.
Porque é que um campo aparece como opcional?
Porque faltava em pelo menos um dos objetos juntados nessa posição. Se colares um único objeto, todos os campos são obrigatórios. Se colares um array de objetos, ou JSON Lines, um campo só continua obrigatório quando todas as amostras o têm. Com a opção "Optional instead of | null", os campos que às vezes eram null também ficam opcionais em vez de receberem | null.
Posso colar JSON Lines ou várias amostras?
Sim. Se o texto não for um único documento JSON mas cada linha não vazia for JSON válido, é lido como JSON Lines e todas as linhas são juntadas num só tipo. Num array JSON normal podes ativar "Top-level array is a list of samples" para que os elementos sejam juntados no próprio tipo raiz, em vez de produzirem type Root = RootItem[].
O que acontece com arrays vazios e valores null?
Um array que esteve sempre vazio não diz nada sobre os seus elementos, por isso fica como unknown[]. Um campo que só foi null fica como null. Os dois casos aparecem nas notas por baixo do resultado. A melhor solução é colar uma amostra onde esses campos tenham valores reais, já que a ferramenta só consegue descrever os dados que vê.
Os textos com datas são convertidos em Date?
Não. O JSON não tem tipo de data, por isso depois de JSON.parse uma data continua a ser uma string, e tipá-la como Date estaria errado em tempo de execução. A ferramenta mantém string, indica nas notas que campos parecem datas ISO 8601 e acrescenta format date-time ou date a esses campos no JSON Schema.
Devo escolher interface ou type?
Para formas simples de objetos são quase equivalentes. As interfaces podem ser estendidas e fundidas, e muitos guias de estilo preferem-nas para modelos de dados. Os aliases type são necessários para uniões e algumas equipas preferem-nos por coerência. Quando a raiz não é um objeto, por exemplo um array ou um valor primitivo, a raiz é sempre um alias type, porque uma interface não os consegue descrever.
Para que serve o separador JSON Schema?
O JSON Schema descreve a mesma estrutura num formato independente da linguagem, que validadores como o Ajv, ferramentas OpenAPI e muitos editores entendem. O schema gerado usa o draft 2020-12, põe os objetos aninhados em $defs ligados por $ref, lista em required os campos presentes em todas as amostras e distingue integer de number. Usa-o como ponto de partida e aperta-o com padrões, enums ou limites.
O meu JSON é enviado para um servidor?
Não. A leitura e a dedução de tipos são JavaScript a correr no teu navegador. Nada do que colas ou abres é enviado ou guardado, por isso podes usar respostas de API reais, tokens ou dados pessoais em segurança.

Sobre JSON para TypeScript

Quantas mais amostras deres, melhores ficam os tipos. Cola um array de registos, vários documentos JSON em formato JSON Lines (um objeto por linha, como em ficheiros de log e exportações NDJSON), ou ativa a opção que trata um array de topo como uma lista de amostras. A ferramenta junta todos os valores que encontra na mesma posição: um campo que falta em alguns objetos fica opcional, um campo que às vezes é null recebe | null (ou fica opcional, se preferires esse estilo), um valor que é texto num registo e número noutro torna-se uma união, e arrays com elementos variados dão (A | B)[]. Arrays que estiveram sempre vazios ficam como unknown[] e campos que só foram null ficam como null, e ambos aparecem nas notas para saberes quais tens de completar à mão. Chaves que não são identificadores válidos, como content-type ou 2fa, são postas entre aspas automaticamente.

Controlas o estilo do resultado: o nome do tipo raiz, interface ou alias type, se as declarações são exportadas, propriedades e arrays readonly, e pontos e vírgulas. Um segundo separador gera um JSON Schema (draft 2020-12) a partir da mesma dedução, com os objetos aninhados em $defs, listas required para os campos presentes em todas as amostras, integer em vez de number quando se aplica, e o formato date-time ou date para textos que parecem datas ISO 8601. O JSON não tem tipo de data, por isso esses campos continuam string no TypeScript. Ambos os resultados podem ser copiados ou descarregados como ficheiro .ts ou .schema.json. Tudo acontece no teu navegador, por isso respostas de API privadas e dados de clientes nunca saem do teu dispositivo.

O sistema de tipos do TypeScript é Turing completo

Os tipos do TypeScript foram pensados para descrever valores JavaScript, mas os tipos condicionais, os aliases recursivos e os template literal types transformaram o verificador de tipos numa pequena linguagem de programação. Em 2017 uma issue no GitHub mostrou que o sistema de tipos é Turing completo, e desde então há quem escreva parsers, aritmética e pequenos interpretadores que correm inteiramente dentro do compilador, com os resultados sob a forma de tipos.

O lado prático disto é a tipagem estrutural. O TypeScript não quer saber como se chama uma interface, só que forma tem, por isso um objeto com os campos certos satisfaz uma interface que nunca viu. É por isso que os tipos gerados a partir de uma amostra JSON encaixam tão bem: descrevem a forma dos dados, e qualquer valor com essa forma é aceite.

Apoiar