Pular para o conteúdo

Converter JSON Schema em tipos TypeScript — Numio

Compila um JSON Schema em interfaces TypeScript com json-schema-to-typescript. Propriedades que não estão em "required" viram opcionais, e objetos recebem uma assinatura de índice, a menos que additionalProperties seja false.

Sua API publica arquivos JSON Schema e você quer interfaces correspondentes para o código cliente que os consome.

JSON Schema

TypeScript

Quando usar

  • Sua API publica arquivos JSON Schema e você quer interfaces correspondentes para o código cliente que os consome.
  • Você mantém arquivos de configuração validados por um schema e quer checagem de tipos onde a configuração é carregada.

Como usar

  1. Cole um JSON Schema no painel JSON Schema. Um "title" define o nome da interface; sem ele, a raiz se chama MySchema.
  2. A conversão roda no navegador enquanto você digita; a página não tem configurações e não adiciona comentário de cabeçalho.
  3. Copie as interfaces do painel TypeScript. A página as formata com Prettier, então elas usam indentação de dois espaços e não têm ponto e vírgula.

JSON Schema

{
  "title": "Address",
  "type": "object",
  "properties": {
    "street": { "type": "string", "minLength": 1 },
    "zip": { "type": "string", "pattern": "^[0-9]{5}$" },
    "country": { "enum": ["US", "CA"], "default": "US" },
    "unit": { "type": ["integer", "null"] },
    "lines": { "type": "array", "items": { "type": "string" }, "maxItems": 3 },
    "geo": { "type": "object", "required": ["lat", "lng"],
      "properties": { "lat": { "type": "number" }, "lng": { "type": "number" } } }
  },
  "required": ["street", "zip"]
}

Interfaces TypeScript

export interface Address {
  street: string
  zip: string
  country?: "US" | "CA"
  unit?: number | null
  lines?: [] | [string] | [string, string] | [string, string, string]
  geo?: {
    lat: number
    lng: number
    [k: string]: unknown
  }
  [k: string]: unknown
}

Detalhes e limitações

Objetos sem "additionalProperties": false recebem [k: string]: unknown, então o tipo continua permitindo chaves extras.

maxItems em um array é expandido em uma união de tuplas, como acontece com "lines" no exemplo.

Entradas $ref locais como #/definitions/Tag viram interfaces exportadas separadas.

A página passa o resultado pelo Prettier sem ponto e vírgula, o que também remove parênteses redundantes em uniões como "US" | "CA".

FAQ

Como os valores null são tipados?

"type": ["integer", "null"] vira (number | null). Tanto integer quanto number são mapeados para number.

Como me livro de [k: string]: unknown?

Adicione "additionalProperties": false a cada schema de objeto; a assinatura de índice é então omitida.

Como a interface raiz é nomeada?

A partir do "title" do schema convertido para PascalCase ("Example Schema" vira ExampleSchema). Sem title, o nome é MySchema.

O schema é enviado a um servidor?

Não. A função compile do json-schema-to-typescript roda no navegador nesta página.

Especificações e referências