Saltar al contenido

Convertir JSON Schema a TypeScript — Numio

Compila un JSON Schema en interfaces de TypeScript con json-schema-to-typescript. Las propiedades que no figuran en "required" pasan a ser opcionales, y los objetos reciben una firma de índice salvo que additionalProperties sea false.

Tu API publica archivos JSON Schema y quieres interfaces equivalentes para el código cliente que los consume.

JSON Schema

TypeScript

Cuándo usarla

  • Tu API publica archivos JSON Schema y quieres interfaces equivalentes para el código cliente que los consume.
  • Mantienes archivos de configuración validados por un esquema y quieres comprobación de tipos donde se carga la configuración.

Cómo usarla

  1. Pega un JSON Schema en el panel JSON Schema. Un "title" define el nombre de la interfaz; sin él, la raíz se llama MySchema.
  2. La conversión se ejecuta en el navegador mientras escribes; la página no tiene opciones de configuración y no añade comentario de cabecera.
  3. Copia las interfaces del panel TypeScript. La página las formatea con Prettier, así que usan sangría de dos espacios y no llevan punto y coma.

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 de 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
}

Detalles y limitaciones

Los objetos sin "additionalProperties": false reciben [k: string]: unknown, de modo que el tipo sigue permitiendo claves adicionales.

maxItems en un array se expande en una unión de tuplas, como ocurre con "lines" en el ejemplo.

Las entradas $ref locales como #/definitions/Tag pasan a interfaces exportadas independientes.

La página pasa el resultado por Prettier sin punto y coma, lo que además elimina los paréntesis redundantes en uniones como "US" | "CA".

FAQ

¿Cómo se tipan los valores null?

"type": ["integer", "null"] pasa a (number | null). Tanto integer como number se asignan a number.

¿Cómo me deshago de [k: string]: unknown?

Añade "additionalProperties": false a cada esquema de objeto; así se omite la firma de índice.

¿Cómo se nombra la interfaz raíz?

A partir del "title" del esquema convertido a PascalCase ("Example Schema" pasa a ExampleSchema). Sin title, el nombre es MySchema.

¿Se envía el esquema a un servidor?

No. La función compile de json-schema-to-typescript se ejecuta en el navegador en esta página.

Especificaciones y referencias