Saltar al contenido

Convertir TypeScript a JSON Schema — Numio

Genera un JSON Schema draft-07 a partir de tipos de TypeScript con ts-json-schema-generator. Cada tipo va en "definitions"; las propiedades opcionales quedan fuera de "required" y los objetos reciben "additionalProperties": false.

Tus tipos de petición y respuesta son interfaces de TypeScript y necesitas JSON Schema para validar con Ajv o para un API gateway.

TypeScript

JSON Schema

Cuándo usarla

  • Tus tipos de petición y respuesta son interfaces de TypeScript y necesitas JSON Schema para validar con Ajv o para un API gateway.
  • Quieres publicar un esquema para un archivo de configuración JSON cuya forma ya está definida como tipo de TypeScript.

Cómo usarla

  1. Pega interfaces o alias de tipo de TypeScript. Las etiquetas JSDoc como @minimum, @format o @pattern se incorporan al esquema.
  2. El código fuente se envía a /api/typescript-to-json-schema, se escribe en un archivo temporal en el servidor y se procesa con todos los tipos expuestos.
  3. Copia el JSON Schema. Si la entrada tiene un solo tipo, la raíz recibe además un $ref a él.

TypeScript

/** A product in the catalog */
export interface Product {
  /** @minimum 0 */
  price: number;
  name: string;
  tags?: string[];
}

JSON Schema (draft-07)

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$ref": "#/definitions/Product",
  "definitions": {
    "Product": {
      "type": "object",
      "properties": {
        "price": {
          "type": "number",
          "minimum": 0
        },
        "name": {
          "type": "string"
        },
        "tags": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      },
      "required": [
        "price",
        "name"
…

Detalles y limitaciones

La página envía tu entrada a una ruta del servidor (/api/typescript-to-json-schema) para convertirla; no se procesa solo en el navegador. Las rutas API de Next.js aceptan por defecto cuerpos de solicitud de hasta 1 MB.

JSDoc se analiza en modo extendido: un comentario de descripción pasa a "description", y etiquetas como @minimum 0 o @minLength 1 pasan a palabras clave.

Los métodos de las interfaces se omiten. Date pasa a un string con format date-time, y las uniones de literales pasan a enum.

bigint no se admite y devuelve un error "Unknown node". Map y Set se describen por su interfaz, un objeto con solo un size numérico, así que usa Record<string, T> o arrays para datos JSON.

FAQ

¿Se incluyen los tipos no exportados?

Sí. Cada tipo de la entrada, exportado o no, se añade a "definitions", y las referencias entre ellos usan $ref.

¿Cómo se representan las propiedades opcionales y anulables?

Las propiedades opcionales quedan fuera de "required". Una unión con null pasa a anyOf con {"type": "null"}.

¿Por qué hay un $ref en la raíz?

Con un solo tipo, el generador apunta la raíz a él con $ref. Con varios tipos, solo se genera "definitions".

Especificaciones y referencias