100 % local — seus dados nunca saem do seu navegador

JSON para io-ts — decodifique e ganhe o tipo

Transforme uma amostra JSON em codecs io-ts. Um codec por objeto, declarado antes do uso, e o TypeOf devolve o tipo estático a partir da mesma declaração.

Instantâneo Privado Zero cookies

Entrada JSON

Saída io-ts

O que esta ferramenta faz

Uma amostra JSON vira códecs io-ts, um const por objeto.

{ "id": 1, "name": "Ada", "address": { "city": "Paris" } }
import * as t from "io-ts";

export const Address = t.type({
  city: t.string,
});

export const Root = t.type({
  id: t.Int,
  name: t.string,
  address: Address,
});

Os filhos são declarados primeiro: códecs são valores de execução, um precisa existir antes que outro o mencione. Um array na raiz ganha o seu próprio códec — export const Users = t.array(UsersItem); — em vez de sobrar para você escrever.

t.Int é um tipo marcado, e isso aparece

t.Int é um refinamento de t.number que carrega uma prova de integralidade. t.TypeOf<typeof Root> dá então { id: Int; … }, não { id: number; … }. Um Int vai aonde se espera um number; o contrário exige um decode. Se esse atrito não compensa a checagem de inteiro na sua base, t.number é uma troca de uma palavra.

Qual dos dois você recebe depende de como o número foi escrito: 3 dá t.Int, 10.0 dá t.number. Até há pouco 10.0 também dava t.Int, e o códec recusava então 10.5 — o registro seguinte. Era um defeito real, encontrado ao escrever estas páginas e corrigido.

O que um códec deixa passar

t.type confere o que conhece e ignora o resto. Uma resposta com três campos a mais decodifica limpa. É a semântica de interface do io-ts, e é o padrão certo para ler a API de outra pessoa — mas se uma chave inesperada tiver de ser um erro, envolva a mesma forma em t.strict, ou em t.exact para removê-la.

Decodificar, em uma linha

import { isRight } from "fp-ts/Either";

const result = Root.decode(payload);
if (isRight(result)) { /* result.right está tipado */ }

PathReporter.report(result) transforma uma falha em caminhos legíveis — útil na primeira vez que um códec recusa uma carga que você julgava certa.

Tudo é obrigatório

Cada chave da amostra cai em t.type, ou seja, obrigatória. O io-ts escreve a opcionalidade num t.partial à parte, unido por t.intersection. Repartir suas chaves entre as duas metades é uma afirmação sobre a API; um documento não pode fazê-la por você.

Privado por padrão

Tudo é executado localmente no seu navegador com JavaScript. Os seus dados nunca são enviados para um servidor, o que torna a ferramenta segura para conteúdo sensível e funciona offline.

Perguntas frequentes

`t.type` recusa propriedades a mais?
Não. `t.type` valida as propriedades que conhece e deixa o resto passar: é o que o io-ts chama de códec de interface. `t.exact` tira as sobrantes, `t.strict` as recusa. O gerador emite `t.type` porque uma amostra não pode dizer qual dos três você quer — é uma decisão sobre a sua API.
Por que `t.TypeOf` me dá `Int` e não `number`?
`t.Int` é um tipo marcado: um `Int` é um `number` carregando a prova de ter sido validado como inteiro. Atribuir um `Int` a um `number` funciona; o contrário exige um decode. Se preferir números simples em todo lugar, troque `t.Int` por `t.number` e abra mão da checagem de inteiro.
Todos os campos são obrigatórios?
Sim, e é o que uma única amostra sustenta. O io-ts escreve a opcionalidade com `t.partial`, em geral combinado em `t.intersection([t.type({…}), t.partial({…})])`. Repartir as chaves entre as duas metades supõe conhecer a API, não ler um documento: a interseção fica com você.

Conversores relacionados