JSON a TypeScript

Pega JSON y obtén interfaces TypeScript al instante.

Ningún dato sale de tu dispositivo

Cómo usar

  1. Pega tu JSON en el panel de la izquierda (objeto o array).
  2. Haz clic en Convertir · las interfaces TypeScript aparecen a la derecha.
  3. Ajusta el nombre raíz y activa las opciones según necesites.
  4. Haz clic en Copiar la salida para copiar el código generado.

Preguntas frecuentes

¿Gestiona los objetos anidados?

Sí. Cada objeto anidado recibe su propia interfaz con nombre. Los elementos de los arrays también se analizan para determinar el tipo de elemento.

¿Qué pasa con arrays de tipos mixtos?

Si un array contiene elementos de tipos distintos, el convertidor usa un tipo unión (p. ej. string | number).

¿Admite arrays JSON en la raíz?

Sí. Si el valor raíz es un array, el convertidor analiza sus elementos y produce la interfaz apropiada así como un alias de tipo para el array.

Qué hace realmente el convertidor

Analiza tu JSON, recorre cada valor y emite un conjunto de declaraciones interface de TypeScript que describen la forma. Cada objeto anidado recibe su propia interfaz con nombre, derivada de la clave de propiedad del padre en PascalCase (un campo user se convierte en una interfaz User). Cuando dos objetos anidados chocan en el nombre, el segundo recibe un sufijo numérico (User, User2). En la raíz, un array se convierte en un alias type Root = RootItem[]; más la interfaz RootItem; un objeto se convierte en una única interfaz Root (o el nombre que pongas en el campo «nombre raíz»).

Ejemplo de entrada y salida:

// Input
{
  "id": 42,
  "name": "Ada",
  "active": true,
  "tags": ["admin", "billing"],
  "profile": { "bio": "Programmer", "link": null }
}

// Output
export interface Root {
  id: number;
  name: string;
  active: boolean;
  tags: string[];
  profile: Profile;
}

export interface Profile {
  bio: string;
  link: unknown;
}

La correspondencia de tipos JSON → TypeScript

Valor JSONTS generado
"hello"string
42 o 3.14number (TS no tiene un tipo entero aparte)
true / falseboolean
nullunknown (el convertidor no puede saber si el campo admite valores nulos o simplemente está ausente en esta muestra)
[]unknown[]
[1, 2, 3]number[]
[1, "x"](number | string)[]
{ "a": 1 }interface con nombre

Para los arrays de objetos de nivel raíz, el convertidor fusiona las claves de todos los elementos en una única interfaz representativa. Es una aproximación razonable cuando los elementos comparten una forma, pero pierde información cuando las formas divergen de verdad (p. ej. un array de eventos heterogéneo). Para ese caso, tendrías que escribir a mano una unión discriminada después de la generación.

Por qué interface para los objetos y type para el array raíz

El Handbook oficial de TypeScript da una heurística de una línea: «Si quieres una heurística, usa interface hasta que necesites usar características de type.» Ambos están tipados estructuralmente y ambos pueden describir formas de objeto, pero interface gana para las formas de objeto porque admite la fusión de declaraciones (reabrir la interfaz para añadir campos), funciona limpiamente con extends y aparece por su nombre en los errores del compilador. Los alias type son obligatorios cuando necesitas uniones de primitivos, intersecciones de varios tipos o nombrar algo que no es un objeto, razón por la cual el array de nivel raíz recibe un alias type Root = RootItem[]; en lugar de una interfaz.

Una nota sobre los nombres: el convertidor usa PascalCase sin el prefijo heredado I (así que User en lugar de IUser). Las guías de estilo modernas de TS (la de Google, la de Microsoft, la de la comunidad de React) prescinden del prefijo casi universalmente. Los nombres de propiedad coinciden exactamente con las claves JSON (camelCase si el JSON usa camelCase, snake_case si usa snake_case). Las claves que no son identificadores JS válidos (que contienen guiones, espacios o que empiezan por un dígito) van entre comillas: "foo-bar": string;.

Lo que esta herramienta no hace (seamos honestos sobre los límites)

Un único ejemplo JSON contiene menos información que un esquema real, así que varias cosas que estaría bien detectar no son posibles solo a partir de la entrada:

Cuándo usar esta herramienta

Primero el código, primero el esquema o directo (dónde encaja esta herramienta)

Tres flujos de trabajo habituales para obtener tipos de TypeScript a partir de datos en tiempo de ejecución:

La elección correcta depende de si tu preocupación es sobre todo la comprobación estática de tipos (esta herramienta es estupenda) o también la seguridad en tiempo de ejecución (recurre a Zod / Effect Schema en su lugar).

Errores comunes

  1. Tratar los tipos generados como una especificación terminada. Son un punto de partida hecho al 70 %. Añade ? para los campos opcionales, | null donde realmente admita nulos y uniones de literales de cadena donde corresponda.
  2. Generar a partir de un único ejemplo cuando la API tiene variantes. Un objeto de usuario que a veces tiene un email y a veces no se generará como «email es obligatorio». Ejecuta varios ejemplos y une los resultados, o edítalo a mano.
  3. Marcar todo como readonly automáticamente. Es útil para los flujos de datos inmutables, pero está mal para los objetos de estado que mutas. Usa la opción readonly con criterio.
  4. Confiar en la precisión con IDs enteros grandes. El number de JavaScript llega como máximo a 253−1. Para los IDs de 64 bits, transmítelos como cadenas y típalos como string.
  5. Confundir interface con type. Herramientas distintas, compensaciones distintas. La heurística del Handbook de TypeScript es «usa interface a menos que necesites una característica que solo type ofrece,» exactamente lo que hace esta herramienta.
  6. Pegar JSON confidencial en un convertidor del lado del servidor. Las respuestas de API reales suelen contener datos de clientes, credenciales e IDs internos. La conversión solo en el navegador (esta herramienta) mantiene los datos en tu máquina.

Más preguntas frecuentes

¿Por qué se marcaron todos mis campos como obligatorios?

Porque un único ejemplo JSON no puede decirle al convertidor qué campos faltan a veces en la API real. Cada clave que aparece en el ejemplo se vuelve obligatoria. Si sabes que un campo es opcional, añade un ? final a mano: email?: string;. Para la detección de opcionalidad con varias muestras, la CLI más sofisticada de quicktype lo gestiona de forma nativa.

¿Por qué mi campo nulo está tipado como unknown?

Porque el convertidor no puede saber, a partir de un único nulo, si el campo siempre admite nulos (string | null) o si simplemente resultó ser nulo en esta muestra (string). unknown es el valor por defecto conservador; TypeScript te obligará a acotar el tipo antes de usar el valor, lo que es más seguro que any. Edítalo a string | null a mano cuando conozcas la intención de la API.

¿Debería usar interface o type?

La heurística del Handbook oficial de TypeScript: usa interface hasta que necesites una característica que solo proporciona type, principalmente los tipos unión, los tipos intersección o nombrar un primitivo. Este convertidor sigue esa regla: interface para cada forma de objeto y type para el alias del array raíz. Algunas guías de estilo recomiendan usar type por defecto en su lugar (Matt Pocock ha defendido públicamente esa postura), pero el valor por defecto convencional es interface para los objetos.

¿Se subirá mi JSON a algún sitio?

No. La conversión es una IIFE de JavaScript autónoma que analiza tu JSON con JSON.parse, recorre el valor y escribe la salida de TypeScript en un área de texto. No hay ningún fetch, ninguna llamada de analítica que transporte el contenido del JSON, ningún servidor. Esto importa porque las respuestas de API reales suelen contener datos de clientes, IDs internos o credenciales que no quieres que circulen por un tercero.

¿Qué pasa con JSDoc, Zod o la validación en tiempo de ejecución?

Esta herramienta emite solo tipos de TypeScript en tiempo de compilación: sin validadores en tiempo de ejecución (sin Zod / Yup / Effect Schema), sin comentarios JSDoc. Si necesitas una validación en tiempo de ejecución que sirva a la vez como tipo estático, escribe el esquema en Zod y usa el z.infer<typeof Schema> de Zod para derivar el tipo. Si tienes un JSON Schema y quieres a la vez validación en tiempo de ejecución y tipos de TS, la combinación habitual es json-schema-to-typescript + AJV.

¿Por qué no hay un prefijo I en los nombres de las interfaces?

Porque la mayoría de las guías de estilo modernas de TypeScript prescinden de él. La Guía de estilo de TypeScript de Google lo desaconseja explícitamente; la comunidad de React ha convergido en PascalCase sin prefijo. La convención heredada IUser vino de la influencia de C# / Java en los primeros tiempos de TypeScript; la práctica actual es User a secas.

Herramientas relacionadas

Formateador y validador JSON gratuito en línea Convertidor JSON a Go Struct Gratis Generador de esquema JSON