JSON a TypeScript: generar interfaces y tipos (guía 2026)
La forma más rápida de pasar de JSON a TypeScript es pegar tu payload en un convertidor de JSON a TypeScript y copiar la interfaz que genera: sin instalar nada, sin subir archivos, listo en tu navegador. Eso cubre el caso de “necesito los tipos ya”.
Pero generar tipos y generar buenos tipos son dos cosas distintas. Un convertidor tiene que adivinar: ¿este campo es opcional o simplemente falta en una muestra? ¿Ese arreglo siempre contiene cadenas, o a veces también números? ¿La cadena de fecha debería convertirse en un Date? Esta guía recorre cómo funciona la inferencia en la práctica, cuándo conviene usar interface frente a type y los errores reales de convertir respuestas de API en vivo en tipos en los que puedas confiar.
Cómo convertir JSON a TypeScript
Convertir JSON a TypeScript se hace en tres pasos:
- Pega tu JSON. Coloca un objeto, un arreglo o una respuesta de API sin procesar en el cuadro de entrada. La conversión se ejecuta al instante, por completo del lado del cliente.
- Ajusta la salida. Elige
interfaceotype, define un nombre raíz comoUseroApiResponse, activa o desactiva la palabra claveexporty escoge?:o| nullpara los campos opcionales. - Copia o descarga. Obtén el TypeScript generado con un clic y pégalo directamente en tu código.
Eso es todo en cuanto al camino transaccional. El convertidor de JSON a TypeScript lee la entrada, infiere un árbol de tipos e imprime las definiciones a la derecha: nada sale de la página. El resto de esta guía trata de entender lo que produjo para que puedas corregir los casos que no puede adivinar.
Cómo se asignan los tipos JSON a TypeScript
Cada valor JSON tiene su contraparte en TypeScript. La correspondencia es casi siempre uno a uno:
| Valor JSON | Tipo TypeScript |
|---|---|
"text" | string |
42, 3.14 | number |
true / false | boolean |
null | null |
[1, 2, 3] | number[] |
{ ... } | interface o type |
Los objetos son donde está el trabajo. Toma un payload típico de usuario en una API REST:
{
"id": 101,
"name": "Ada Lovelace",
"email": "ada@example.com",
"active": true,
"roles": ["admin", "user"]
}
Un convertidor produce esta interfaz de TypeScript a partir del JSON:
export interface User {
id: number;
name: string;
email: string;
active: boolean;
roles: string[];
}
Cada escalar se asigna a su tipo primitivo, y el arreglo roles se convierte en string[]. Coloca eso en tu cliente de API y obtienes autocompletado y comprobaciones en tiempo de compilación sin esfuerzo.
Cómo infiere los tipos el convertidor
La parte interesante es el algoritmo de inferencia. Cuatro reglas cubren casi todo lo que le pongas delante.
Inferencia estructural: una interfaz con nombre por cada objeto
Cada forma de objeto distinta se convierte en su propia interfaz con nombre. Los objetos anidados no se colapsan en tipos en línea: se extraen en definiciones separadas y referenciadas:
{
"order": {
"id": "A-1",
"total": 42.5,
"customer": { "name": "Sam", "vip": false }
}
}
export interface Root {
order: Order;
}
export interface Order {
id: string;
total: number;
customer: Customer;
}
export interface Customer {
name: string;
vip: boolean;
}
Las formas idénticas se deduplican, de modo que dos campos con la misma estructura comparten una sola interfaz en lugar de producir copias.
Fusión de arreglos: inferir campos opcionales
Cuando pasas un arreglo de objetos, el convertidor los fusiona clave por clave. Si una clave aparece en algunos elementos pero no en otros, se marca como opcional:
{
"users": [
{ "id": 1, "nick": "x" },
{ "id": 2 }
]
}
export interface Root {
users: User[];
}
export interface User {
id: number;
nick?: string;
}
id está en todos los elementos, así que sigue siendo obligatorio. nick falta en el segundo usuario, por lo que se convierte en nick?: string. Por eso una sola muestra rara vez es suficiente: consulta la sección de errores más abajo.
Tipos de unión para arreglos mixtos
Los arreglos no tienen por qué ser homogéneos. Cuando los elementos tienen tipos distintos, el convertidor los reúne en una unión:
{
"tags": ["a", "b"],
"meta": [1, "two"]
}
export interface Root {
tags: string[];
meta: (string | number)[];
}
tags contiene cadenas de manera uniforme, así que string[]. meta mezcla un número y una cadena, lo que produce (string | number)[]. Un arreglo vacío no se puede inferir en absoluto y recurre a unknown[]: algo honesto, ya que no hay nada que aprender de cero elementos.
Opcional frente a null: ?: frente a | null
Parecen similares pero significan cosas distintas. Un campo marcado con ?: puede estar ausente por completo del objeto. Un campo tipado con | null siempre está presente, pero puede contener el valor null:
{ "score": null }
export interface Root {
score: number | null;
}
Aquí score está presente con un null explícito, así que se tipa como number | null: el valor existe, simplemente es null. Compáralo con nick?: string del ejemplo del arreglo, donde la clave puede faltar por completo. Usa ?: cuando la API pueda omitir la clave, y | null cuando envíe la clave con un valor null. La mayoría de los convertidores te dejan controlar cómo se representa esto con un interruptor.
interface vs type: ¿cuál deberías usar?
Ambos pueden describir la forma de un objeto. Así es como decidir:
| Necesidad | Usa |
|---|---|
| Forma de objeto plana a partir de JSON | interface |
Unión (A | B) o intersección (A & C) | type |
| Fusión de declaraciones / extender entre archivos | interface |
| Tipos mapeados o condicionales | type |
| Mensajes de error del editor algo más limpios | interface |
Para datos que salieron de un objeto JSON, interface es la opción convencional y produce errores de compilación apenas más agradables. En cuanto necesitas una unión —digamos un Result que es un éxito o un error— tienes que cambiar a un type, porque las interfaces no pueden expresar uniones:
type ApiResult =
| { status: "ok"; data: User }
| { status: "error"; message: string };
Un buen valor por defecto: genera una interface para objetos JSON planos y conviértela en un type cuando la forma necesite una unión o intersección. El Manual de TypeScript cubre los casos límite si quieres la comparación completa. Cuando necesitas un alias json to typescript type en lugar de una interfaz, la mayoría de los convertidores ofrecen un único interruptor para cambiar toda la salida.
quicktype vs json-to-ts vs herramientas en línea vs hacerlo a mano
No hay una única forma óptima de generar tipos de TypeScript: depende de dónde vive el JSON y con qué frecuencia cambia.
| Enfoque | Mejor para | Compromiso |
|---|---|---|
| quicktype | Salida multilenguaje, generar código de validación en tiempo de ejecución | Más pesado; más salida de la que sueles necesitar |
| json-to-ts (biblioteca) | Generación de código en tiempo de compilación integrada en un script o pipeline | Requiere configuración y una cadena de herramientas de Node |
| Herramienta en línea basada en el navegador | Conversiones puntuales, payloads sensibles, cero instalación | Pegar manualmente cada vez |
| Escribir los tipos a mano | Objetos diminutos, aprender el sistema de tipos | Tedioso y propenso a errores a escala |
Elige quicktype cuando necesites tipos en varios lenguajes o quieras que emita validadores junto con los tipos. Elige la biblioteca json-to-ts cuando la conversión pertenezca a un paso de compilación. Para una conversión rápida —especialmente de un payload que contenga tokens, IDs de clientes o cualquier cosa que prefieras no pegar en un servicio remoto— una herramienta de navegador gana en privacidad y velocidad. Nuestro convertidor de JSON a TypeScript se ejecuta por completo del lado del cliente: el JSON nunca sale de la página y no hay nada que instalar ni actualizar.
Los tipos no son validación: el puente hacia las comprobaciones en tiempo de ejecución
Esto confunde a muchos equipos, así que conviene dejarlo claro: los tipos de TypeScript se borran en tiempo de compilación y no hacen nada en tiempo de ejecución. Una interface User generada no comprobará que una respuesta de API real coincida con ella. Si el servidor envía id como cadena en lugar de número, TypeScript cree felizmente tu anotación de tipo mientras los datos reales mienten.
Para generate typescript types y además hacerlos cumplir sobre datos en vivo, combina los tipos con un validador en tiempo de ejecución:
- zod: define un esquema una vez, infiere el tipo estático a partir de él y analiza las respuestas en tiempo de ejecución.
- io-ts: validación basada en códecs, popular en bases de código funcionales.
- JSON Schema + Ajv: esquemas independientes del lenguaje validados en tiempo de ejecución, útiles cuando el contrato se comparte entre servicios.
Un patrón común es generar la interfaz para el soporte del editor y luego escribir un esquema zod equivalente como la comprobación de frontera real:
import { z } from "zod";
const UserSchema = z.object({
id: z.number(),
name: z.string(),
email: z.string().email(),
active: z.boolean(),
roles: z.array(z.string()),
});
type User = z.infer<typeof UserSchema>;
// Lanza un error si la respuesta real no coincide con el esquema.
const user = UserSchema.parse(await res.json());
Si vas a tomar el camino de los esquemas, nuestra guía de validación con JSON Schema recorre de principio a fin cómo escribir y hacer cumplir esquemas.
Errores comunes al tipar JSON
Los tipos generados son un punto de partida, no un producto terminado. Cuídate de estos.
snake_case frente a camelCase. Los convertidores conservan las claves tal cual. Un payload al estilo de GitHub con public_repos produce public_repos: number, no publicRepos. Si tu base de código prefiere camelCase, tendrás que convivir con los tipos en snake_case o añadir una capa de mapeo que renombre los campos al entrar.
Las cadenas de fecha siguen siendo string. Un campo como "2026-06-01T00:00:00Z" se tipa como string, no como Date. Es algo deliberado: JSON no tiene tipo de fecha, y adivinar mal es peor que ser honesto. La conversión de cadena a Date pertenece a tu capa de análisis, donde tú la controlas.
Filtración de any y unknown. Los arreglos vacíos se convierten en unknown[] y las estructuras profundamente mixtas pueden degradarse en tipos laxos. No son errores; es el convertidor admitiendo que no puede inferir a partir de datos insuficientes. Ajústalos a mano una vez que conozcas la forma real.
Explosión por anidamiento profundo. Un payload muy anidado genera una larga cadena de interfaces pequeñas. Eso suele estar bien y es más legible que un único tipo en línea gigante, pero conviene aplanar las formas que no se ganan su propio nombre.
La trampa de la muestra única. Esta es la grande. Los campos opcionales solo se pueden inferir a partir de varios elementos de un arreglo: un solo objeto no puede decirle al convertidor qué claves a veces están ausentes. Reúne primero un arreglo representativo de respuestas. Un formateador JSON resulta útil para pegar e inspeccionar varias muestras una al lado de la otra antes de convertir, y si vas a alimentar entradas no estándar como JSONC, lee nuestra guía de JSON5 / JSONC: el convertidor necesita JSON estrictamente válido.
Preguntas frecuentes
¿Cómo convierto JSON a una interfaz de TypeScript?
Pega tu JSON en un convertidor de JSON a TypeScript. Lee la entrada en tu navegador y genera una interfaz de TypeScript al instante. Haz clic en Copiar para obtener el resultado: sin subir nada, sin cuenta, sin complemento que instalar.
¿Debería usar interface o type para datos JSON?
Usa interface para formas de objeto planas a partir de JSON: es convencional y da errores del editor algo más claros. Cambia a type cuando necesites una unión o intersección, ya que las interfaces no pueden expresarlas.
¿Cómo se manejan los objetos y arreglos anidados?
Los objetos anidados se convierten en interfaces separadas con nombre (un campo address produce una interfaz Address). Los arreglos de objetos se fusionan clave por clave en una sola interfaz de elemento; los arreglos de primitivos se convierten en arreglos tipados como string[].
¿Cómo se tipan los campos opcionales y null?
Una clave que falta en algunos elementos de un arreglo se marca como opcional (nick?: string). Una clave que siempre está presente pero contiene null se tipa con | null (score: number | null). Las dos describen situaciones distintas: ausente frente a presente pero null.
¿Los tipos de TypeScript validan el JSON en tiempo de ejecución?
No. Los tipos de TypeScript se borran en tiempo de compilación y no comprueban los datos en tiempo de ejecución. Para validar una respuesta de API real, combina los tipos generados con un validador en tiempo de ejecución como zod, io-ts o JSON Schema con Ajv.
quicktype vs json-to-ts vs un convertidor en línea, ¿cuál es mejor?
quicktype encaja con la salida multilenguaje y los validadores en tiempo de ejecución; la biblioteca json-to-ts encaja con la generación de código en tiempo de compilación; un convertidor en línea encaja con conversiones rápidas, privadas y puntuales con cero instalación. Para payloads sensibles, una herramienta de navegador del lado del cliente mantiene los datos fuera de cualquier servidor.
¿Por qué las cadenas de fecha se tipan como string en lugar de Date?
JSON no tiene tipo de fecha, así que una fecha no es más que una cadena en la transmisión. Tiparla como string es honesto y estable; convertirla a Date es una decisión de tu capa de análisis, donde controlas el formato y el manejo de errores.
¿Mis datos JSON son privados al usar un convertidor en línea?
Con una herramienta del lado del cliente, sí. La conversión se ejecuta por completo en tu navegador usando JavaScript, así que el JSON —incluidos tokens, IDs y datos de clientes— nunca sale de la página y nunca se envía a un servidor.