ToolActToolAct

JSON a TypeScript

Convierte automáticamente datos JSON a interfaces o definiciones de tipo TypeScript

Entrada JSON
Líneas: 1 | Caracteres: 0
Salida TypeScript
// Las definiciones de tipo TypeScript se generarán automáticamente
Tipos: 0 | Líneas: 1

¿Qué es JSON a TypeScript?

JSON to TypeScript analiza una estructura JSON y genera interfaces o alias de tipo de TypeScript a partir de ella. Es útil cuando respuestas de API, archivos de configuración, payloads de ejemplo o datos simulados deben entrar rápidamente en un proyecto frontend o Node.js tipado. La herramienta infiere objetos, arrays, propiedades anidadas, campos opcionales y tipos básicos, convirtiendo datos sin formato en una base práctica para autocompletado y comprobaciones en compilación. Aun así, requiere revisión: un ejemplo JSON puede no cubrir todos los campos, los arrays vacíos no muestran la forma de sus elementos y una API real puede devolver null o variantes.

Cómo usar

Cómo usar

  1. Pega datos JSON en el panel izquierdo, o haz clic en el botón de ejemplo para cargar uno
  2. Configura las opciones: define el nombre del tipo raíz, elige el estilo de interfaz/tipo y si quieres añadir export
  3. Las definiciones de tipo TypeScript correspondientes se generan automáticamente a la derecha
  4. Haz clic en el botón Copy para copiar las definiciones de tipo generadas al portapapeles
  5. Pega las definiciones de tipo en tu proyecto TypeScript para usarlas

Consejos de generación de tipos

  • Usa muestras de JSON representativas. Un solo ejemplo no puede revelar cada campo opcional, valor nullable o tipo unión en una API real.
  • Revisa los nombres generados antes de confirmarlos, especialmente para objetos anidados donde los nombres de interfaz automáticos pueden ser demasiado genéricos.

Casos de uso

Crear tipos TypeScript a partir de ejemplos de APIPega una respuesta JSON, elige el estilo interface o type alias, y genera un tipo raíz con declaraciones anidadas. La herramienta fusiona las formas de objetos encontradas dentro de arrays, por lo que los registros repetidos pueden convertirse en un modelo práctico del lado del cliente en lugar de un montón de ejemplos sin relación.
Adaptarse rápidamente a las convenciones de nombres del proyectoLas opciones para declaraciones exportadas, propiedades opcionales y prefijos I/T permiten adaptar el código generado al estilo existente del proyecto antes de copiarlo. Renombrar el tipo raíz resulta útil al convertir una muestra cruda de un endpoint en un modelo de dominio como UserProfileResponse o InvoiceLine.
Inicializar mocks y fixtures de forma seguraCuando un fixture crece más rápido que su definición de tipo, convertir la muestra JSON más reciente revela campos ausentes, valores nullable, arrays vacíos y tipos primitivos mezclados. Es una forma rápida de mantener las pruebas y los datos de demostración alineados con la forma que realmente consume la interfaz.
Generar tipos separados para variantes de uniónCuando un campo puede ser una cadena, un número o un objeto anidado según el caso, divide las muestras JSON y ejecuta cada una por el generador para obtener variantes limpias en lugar de una unión ruidosa. Ensambla manualmente las variantes con una unión discriminada para un narrowing correcto en sentencias switch. Ten en cuenta que la herramienta marca cada campo observado, pero nunca uno no observado, por lo que un array vacío [] produce unknown[] en lugar de una forma fantasma, y una unión inferida de primitivos mezclados suele ocultar el discriminador que realmente necesitas para el switch.
Comparar los tipos generados con las definiciones OpenAPIPasa una respuesta real por el convertidor y luego compara el resultado con los tipos oficiales de OpenAPI o generados por el backend. Detecta campos ausentes, nulabilidad incorrecta y discrepancias en elementos de array que una sola muestra no puede exponer, especialmente cuando el contrato de la API se ha desviado del comportamiento en producción. El flag ? del generador rastrea la presencia en múltiples objetos de la misma entrada; una sola muestra nunca lo establece, por lo que un campo genuinamente obligatorio seguirá pareciendo opcional hasta que proporciones un segundo payload que también lo omita. Las claves en snake_case como user_id se conservan tal cual en lugar de convertirse a camelCase, por lo que el resultado se alinea con los SDKs del servidor que emiten JSON en snake_case sin renombrar.

Principio técnico

JSON a TypeScript es fundamentalmente un proceso de 'inferencia de estructura'. La herramienta recorre recursivamente cada nodo del árbol JSON, mapeando el tipo en tiempo de ejecución de cada valor a un tipo TypeScript: string -> string, number -> number, boolean -> boolean, null -> null, object -> sub-interfaz, array -> array del tipo del elemento. La salida es un conjunto de declaraciones `interface` de TypeScript (o alias `type` si se selecciona el modo de salida 'type') más las interfaces anidadas extraídas de campos con valores de objeto. La parte difícil de la inferencia es la decisión entre unión y tipo único para arrays. Cuando todos los elementos de un array tienen el mismo tipo, la salida es `T[]` (array homogéneo). Cuando los elementos tienen tipos diferentes, la salida es la unión de esos tipos: `[1, 'a', true]` se convierte en `(number | string | boolean)[]`. Cuando la entrada es un objeto que mezcla valores literales y estructurados (p. ej. `{ id: 1, name: 'Alice', tags: ['admin', 'editor'] }`), cada campo obtiene su propio tipo; para objetos con valores primitivos mixtos la página emite una sola interfaz, no una unión, porque es lo que el código TypeScript espera (y coincide con la naturaleza del objeto JSON como tipo registro). Los múltiples objetos de muestra (el caso de uso típico: pegar un array JSON) se fusionan intersecando sus formas. Los campos presentes en cada muestra se vuelven obligatorios; los campos que faltan en alguna muestra se vuelven opcionales (`fieldName?: T`). Este es el comportamiento correcto para respuestas de API: una respuesta 200 OK tiene una forma, una 404 tiene otra, y la unión de ambas es el tipo TS correcto. Para una sola muestra, todos los campos son obligatorios. La normalización de nombres es donde la mayoría de las herramientas de 'JSON a TS' fallan. Las claves JSON suelen estar en snake_case (`user_id`, `created_at`) o camelCase (`userId`, `createdAt`); la convención de TypeScript es PascalCase para nombres de interfaz (`UserProfile`, `AuditEntry`) y camelCase para nombres de propiedad. La página convierte las claves JSON a camelCase (o las preserva si ya están en camelCase o son una sola palabra) y PascalCase para nombres de interfaz. Los objetos internos se extraen en interfaces con nombre: `{ user: { name, age } }` se convierte en `interface User { name: string; age: number; }` y el padre se convierte en `interface Root { user: User; }`. Las estructuras recursivas (un nodo de árbol con un campo `children: TreeNode[]`) obtienen una autorreferencia usando una declaración `type` adelantada en lugar de `interface` para que el ciclo esté bien definido. El interruptor 'root' es la diferencia entre un array raíz y un objeto raíz. Un array JSON se convierte en `type Root = Item[]` o `interface Root { items: Item[]; ... }` dependiendo del interruptor de envoltura de array. Un objeto JSON se convierte en una interfaz plana en el nivel superior. Las cadenas de fecha (RFC 3339 / ISO 8601) pueden etiquetarse como `Date` en lugar de `string`; los UUID, emails y URLs pueden etiquetarse como tipos con marca (`type UUID = string & { readonly __brand: 'UUID' };`) cuando el interruptor de modo estricto está activado. La generación de JSDoc es heurística: un campo llamado `email` (y cuyo valor coincide con un regex básico de email) recibe un comentario como `/** user email */` encima de la declaración. Lo mismo para `id`, `name`, `url`, `created_at`/`createdAt`, `updated_at`/`updatedAt`, `description`, `title`. Los comentarios son de mejor esfuerzo y no pretenden ser escritos por humanos; son un punto de partida que los humanos editarán. La página también emite modificadores `export` para que la salida pueda insertarse directamente en cualquier archivo TS, y un encabezado `// generated by json-to-typescript, do not edit by hand` para desalentar ediciones manuales que se sobrescribirían la próxima vez que el esquema se regenere.

  • Mapeo de tipos atómicos: los string/number/boolean/null de JSON se mapean uno a uno a los string/number/boolean/null de TypeScript. Los enteros grandes (>2^53) necesitan BigInt; la página los etiqueta como `bigint` cuando el valor excede Number.MAX_SAFE_INTEGER.
  • Inferencia de tipo de array: recorre todos los elementos y toma la unión de sus tipos; los tipos idénticos colapsan a `T[]`, los tipos distintos forman `(A | B | C)[]`. Los arrays vacíos se convierten en `unknown[]` ya que el tipo del elemento es desconocido.
  • Extracción de objetos anidados: los objetos internos se elevan automáticamente a interfaces con nombre. Las estructuras recursivas usan `type Name = ...` (no `interface`) para que la referencia adelantada esté bien definida en el verificador de tipos de TypeScript.
  • Detección de campos opcionales: cuando se fusionan múltiples objetos de muestra, los campos presentes en cada muestra se vuelven obligatorios; los campos que faltan en alguna muestra se vuelven opcionales (`fieldName?: T`). La entrada con una sola muestra marca todos los campos como obligatorios.
  • Convención de nombres: las claves JSON se convierten a camelCase para nombres de propiedad (user_id -> userId, created_at -> createdAt) y PascalCase para nombres de interfaz (UserProfile, AuditEntry). Las claves de una sola palabra se preservan; los números en claves se preservan; los dígitos iniciales se prefijan con guion bajo para mantener identificadores TS válidos.
  • Interruptor raíz: array raíz -> `export type Root = Item[]` (o envuelto en `{ items: Item[]; }` si wrap-array está activado); objeto raíz -> un solo `export interface Root { ... }`. Las estructuras recursivas obtienen primero una declaración adelantada stub.
  • Comentarios JSDoc: generación heurística de comentarios para nombres de campo conocidos (email, id, name, url, createdAt, updatedAt, description, title). La salida incluye modificadores `export` y un encabezado `// generated, do not edit by hand` para desalentar ediciones manuales.
  • Modo estricto: activación opcional de tipos con marca (UUID, Email, URL, Date), modificadores readonly, exactOptionalPropertyTypes y noUncheckedIndexedAccess. La página emite `type UUID = string & { readonly __brand: 'UUID' };` cuando el modo estricto está activado, para que el código descendente pueda distinguir una cadena sin tipo de un valor tipado.

Ejemplos

Objeto simple a interface

{"id": 1, "name": "Alice", "active": true}
->
interface User {
  id: number;
  name: string;
  active: boolean;
}

Objeto anidado genera sub-interfaces

{"user": {"name": "Alice", "address": {"city": "NYC"}}}
->
interface Root {
  user: User;
}
interface User {
  name: string;
  address: Address;
}
interface Address {
  city: string;
}

Array a tupla readonly

[{"id": 1}, {"id": 2}]
->
interface Item {
  id: number;
}
type Root = readonly Item[];

Preguntas frecuentes

¿Qué construcciones de TypeScript genera?

Interfaces por defecto: una por cada forma de objeto. Los campos opcionales usan el marcador ?. Los arrays se convierten en T[]. Los arrays de tipos mixtos se convierten en una unión. Las cadenas con formatos reconocidos (por ejemplo, fechas ISO) se mantienen como string a menos que actives los tipos branded. Algunas páginas ofrecen alias 'type' en lugar de 'interface'.

¿Cómo se manejan los objetos anidados?

Cada forma anidada distinta obtiene su propia interface, nombrada según la ruta de la propiedad (User, UserAddress, UserPreferences). Si dos propiedades comparten la misma forma, el generador puede deduplicarlas o no según los ajustes; revisa la salida y consolida a mano si es necesario.

¿Las propiedades son obligatorias u opcionales?

Por defecto, las propiedades presentes en la muestra se marcan como obligatorias. Las propiedades que aparecen en algunos elementos del array pero no en otros se marcan como opcionales con `?`. Activa 'todas opcionales' si tu muestra es un ejemplo entre muchas formas posibles.

¿Cómo maneja null y undefined?

null en JSON se convierte en `null` en TypeScript (no undefined). Una propiedad que a veces es una cadena y a veces null se convierte en `string | null`. JSON no tiene undefined, por lo que el generador nunca emite `undefined` directamente.

¿Y los tipos unión y las uniones discriminadas?

Cuando un array contiene formas de objeto mixtas, el generador emite una unión de interfaces. No detecta automáticamente un campo discriminador; reescribe a mano como unión discriminada (por ejemplo, etiqueta 'kind') si quieres un estrechamiento de tipos exhaustivo.

¿Se sube el JSON?

No. La conversión se ejecuta en tu navegador con un parser JSON basado en JS y plantillas de cadena. El JSON pegado no sale de tu dispositivo.

¿Coincidirá con lo que realmente devuelve mi backend?

Solo en la medida en que lo haga la muestra. Valida siempre los datos en tiempo de ejecución contra un esquema (Zod, io-ts, Yup): los tipos de TypeScript se borran en tiempo de ejecución y no detectarán un backend que se desvíe del ejemplo.