Tools mentioned in this article
Open the browser-based tool while you read and try the workflow immediately.
Escribir definiciones de tipo para respuestas de API es inevitable en el desarrollo con TypeScript. Escribir a mano una interface mientras lees un objeto JSON profundamente anidado es tedioso y un caldo de cultivo para errores tipográficos.

Este artículo muestra en qué tipos de TypeScript se convierte el JSON real, con ejemplos concretos de conversión, junto con los consejos y advertencias de la generación automática.
Lo básico: un objeto plano
Empecemos con un ejemplo sencillo.
{
"id": 42,
"name": "Alice",
"isActive": true
}
Esto se convierte en el siguiente tipo. El tipo de cada valor (number / string / boolean) se infiere mecánicamente a partir de los datos reales.
interface User {
id: number;
name: string;
isActive: boolean;
}
Anidamiento y arreglos
Las respuestas de API reales contienen objetos anidados y arreglos.
{
"id": 42,
"name": "Alice",
"roles": ["admin", "editor"],
"profile": {
"age": 30,
"city": "Tokyo"
}
}
La convención es tipar los arreglos a partir de su tipo de elemento (string[]) y extraer los objetos anidados en sus propias interfaces.
interface Profile {
age: number;
city: string;
}
interface User {
id: number;
name: string;
roles: string[];
profile: Profile;
}
Trampas fáciles de pasar por alto
null y propiedades opcionales
Cuando el JSON contiene null, ese valor por sí solo no te dice si el campo es “siempre anulable” o “simplemente resultó ser null”.
{ "nickname": null, "deletedAt": null }
Una conversión mecánica produce nickname: null, pero en la práctica string | null o nickname?: string suele ser lo correcto. Ajústalo a mano tras la generación para que coincida con la especificación de la API.
interface User {
nickname: string | null; // también puede llegar un valor
deletedAt?: string; // el campo en sí puede no estar
}
Cuidado con los números como cadenas
Las API que envuelven números en cadenas, como "price": "1980", son comunes. Los generadores lo infieren como string. Si vas a hacer cálculos, cambia el tipo a number o convierte al recibir; decide una política de antemano.
Los arreglos vacíos no tienen tipo determinable
Un arreglo vacío como "tags": [] no da tipo de elemento y tiende a convertirse en never[] o any[]. Usa una muestra con elementos, o especifica string[] a mano tras generar.
Pasos para usar la generación automática
- Copia una respuesta real de la pestaña Network del navegador o de la salida de curl
- Pégala en el generador de JSON → TypeScript
- Renombra la interfaz raíz de
Roota algo comoUserResponse - Ajusta los campos
nully opcionales según la especificación - Pega en tu proyecto: listo
La clave es usar una muestra representativa con todos los campos presentes. Una muestra pobre se perderá campos opcionales y variaciones de tipo.
Cuando los tipos no bastan: recurre a Zod
Los tipos de TypeScript son una comprobación en tiempo de compilación. No hay garantía de que los datos que realmente llegan de una API externa coincidan con tus tipos. Si también quieres validación en tiempo de ejecución, genera un esquema con el generador de JSON → Zod y añade una comprobación de entrada con schema.parse(data). Zod además infiere tipos, lo que te permite gestionar tipos y validación en un solo lugar.
Preguntas frecuentes
Renombrar la interfaz raíz cada vez es tedioso.
La mayoría de las herramientas emiten la raíz como un genérico Root. Lo más fácil es hacer un buscar-y-reemplazar a la convención de tu proyecto (ApiResponse, UserProfile, …) tras copiar. Los nombres de las interfaces anidadas suelen reflejar su contenido, así que corregir solo la raíz basta en la mayoría de los casos.
¿Cómo uso una API en snake_case como camelCase?
Los tipos generados reflejan las claves del JSON, así que obtendrás nombres como created_at. Para estandarizar en camelCase, convierte en el límite de la API (una función de mapeo o una librería de camelización). Mantén los tipos acordes a la realidad de la API y haz la conversión explícita para evitar confusiones.
¿Debo crear primero el tipo de TypeScript o el esquema de Zod?
Si necesitas validación en tiempo de ejecución, crea el esquema de Zod y deriva el tipo con z.infer: así todo queda en un solo lugar. Si una comprobación en tiempo de compilación basta para datos internos de confianza, generar solo el tipo de TypeScript es suficiente. Usa Zod para “entradas no confiables” como API externas y datos de formularios.