¿Odias los anuncios? Ir Sin publicidad Hoy

JSON a TypeScript Generar interfaces automáticamente a partir de respuestas de API

Actualizado en

Escribir manualmente interfaces de TypeScript para cada respuesta de API es tedioso y propenso a errores. Aprende a generar automáticamente interfaces precisas a partir de datos JSON reales, luego añade validación en tiempo de ejecución con Zod — porque los tipos desaparecen en tiempo de ejecución y `any` no es una solución.

JSON a TypeScript: Generación automática de interfaces a partir de respuestas de API 1
ANUNCIO · ¿ELIMINAR?

Acabas de obtener datos de una API de terceros. La respuesta es un bloque denso de JSON — objetos anidados, arrays, campos nulos — y ahora debes determinar cómo tipificarlo en TypeScript. Por lo tanto, abres un nuevo archivo y empiezas a escribir, y tras 20 minutos tienes algo que probablemente coincida con los datos reales. Probablemente. interface User { ... }Existe una manera mejor. Herramientas que convierten JSON directamente en interfaces de TypeScript reducen ese trabajo de 20 minutos a segundos. Este artículo explica qué parecen esos tipos generados, cómo manejar casos difíciles (nulos, uniones, anidación profunda), y por qué es recomendable combinar tipos generados con esquemas de Zod para detectar desviaciones de forma en tiempo de ejecución, no solo en tiempo de compilación.

Por qué las interfaces de TypeScript para respuestas de API son importantes

La ventaja de TypeScript es detectar errores antes de que tu código se ejecute. Sin respuestas tipadas de API, estás en la oscuridad: accediendo a propiedades que podrían no existir, tratando valores opcionales como obligatorios, o convirtiendo silenciosamente una cadena

a algo inesperado en el flujo de trabajo. "null" Considera esta escena común:

Si hubieras tipado correctamente la respuesta — con

const user = await fetchUser(id);
console.log(user.address.city); // TypeError at runtime if address is null

— TypeScript habría marcado inmediatamente ese acceso. El compilador es tu primera línea de defensa, pero solo si te proporciona algo para trabajar. address: Address | null Escribir interfaces manualmente para cada API es tedioso y propenso a errores. Lees mal el esquema, omites un campo opcional o copias y pegas una versión obsoleta. Generar interfaces directamente a partir de datos JSON elimina ese error humano del proceso.

Lo que produce la conversión JSON a TypeScript

Toma una respuesta de API sencilla:

Pégala en el

{
  "id": 42,
  "username": "jsmith",
  "email": "j@example.com",
  "createdAt": "2024-01-15T10:30:00Z",
  "role": "admin",
  "profile": {
    "bio": "Developer",
    "avatar": null
  }
}

y obtienes: Generador de Interfaces de TypeScript a partir de JSON Algunas cosas a tener en cuenta:

interface Profile {
  bio: string;
  avatar: null;
}

interface RootObject {
  id: number;
  username: string;
  email: string;
  createdAt: string;
  role: string;
  profile: Profile;
}

Los objetos anidados se convierten en sus propias interfaces

  • se extrae automáticamente en lugar de incluirse.Profile Las fechas se tipifican como
  • — el JSON no tiene un tipo de fecha, por lo que las cadenas ISO permanecen como cadenas. Tendrás que parsearlas tú mismo. string se tipifica como literal
  • avatar: null — lo cual es preciso pero incompleto. Más sobre eso a continuación. null Manejo de casos difíciles

Campos nulos

Cuando un campo es

en tu JSON de ejemplo, el generador lo tipifica como null . Pero en la práctica, ese campo probablemente cambia entre un valor real y nulo según los datos. Querrás ajustarlo manualmente: nullLo mismo aplica para campos opcionales que, por casualidad, están presentes en tu muestra — agrega

// Generated
avatar: null;

// What you actually want
avatar: string | null;

a cualquier propiedad que pueda faltar en algunas respuestas. ? Arrays de objetos se manejan de forma limpia. Dado:

Matrices

El generador produce:

{
  "posts": [
    { "id": 1, "title": "Hello", "published": true },
    { "id": 2, "title": "World", "published": false }
  ]
}

Si tus ejemplos de JSON muestran un campo que contiene tipos diferentes en registros distintos — por ejemplo, un

interface Post {
  id: number;
  title: string;
  published: boolean;
}

interface RootObject {
  posts: Post[];
}

Tipos de Unión

que puede ser un número o una cadena — deberías representarlo como una unión. Los tipos generados no capturarán esto a partir de un solo ejemplo, por lo que vale la pena revisar la documentación de la API: value Anidación profunda

value: string | number;

La anidación profunda es donde el tipado manual realmente se desmorona — y donde los generadores ganan su lugar. Una respuesta con tres o cuatro niveles de anidación se descompone en una jerarquía limpia de interfaces nombradas, cada una responsable de su propia forma.

La brecha entre tipos en tiempo de compilación y la realidad en tiempo de ejecución

Aquí está lo que a menudo omiten los nuevos usuarios de TypeScript:

los tipos desaparecen en tiempo de ejecución. TypeScript se compila a JavaScript, y JavaScript no tiene concepto de interfaces. Si tu API devuelve una forma que no coincide con el tipo declarado, TypeScript no lo sabrá — y no te lo dirá. Esto hace que el patrón común de casting de respuestas de API sea realmente peligroso:

Ese casting le dice a TypeScript “confía en mí, esto es un

const data = await response.json() as User; // No validation, just trust

” — pero TypeScript no tiene forma de verificarlo. Si la API cambia su forma o devuelve un objeto de error en su lugar, tu código se rompe en tiempo de ejecución de maneras que el compilador nunca te advirtió. UserLa solución es la validación en tiempo de ejecución.

Zod para validación en tiempo de ejecución

Zod

es una biblioteca de validación de esquemas especializada en TypeScript. Definirás un esquema una vez, lo usarás para analizar datos entrantes y obtendrás un valor completamente tipado — o un error detallado si la forma no coincide. Sin casting, sin suposiciones. Usando el mismo ejemplo de JSON anterior, el

produce: Generador de esquemas Zod a partir de JSON Observa la última línea:

import { z } from "zod";

const ProfileSchema = z.object({
  bio: z.string(),
  avatar: z.null(),
});

const RootObjectSchema = z.object({
  id: z.number(),
  username: z.string(),
  email: z.string(),
  createdAt: z.string(),
  role: z.string(),
  profile: ProfileSchema,
});

type RootObject = z.infer<typeof RootObjectSchema>;

deriva el tipo de TypeScript directamente del esquema. Obtienes tanto seguridad de tipo en tiempo de compilación como validación en tiempo de ejecución desde una única fuente de verdad. z.infer Usarla en el límite de la solicitud se ve así:

Ajusta el esquema generado para manejar los casos nulos que el generador no puede inferir a partir de un solo ejemplo:

const rawData = await response.json();
const user = RootObjectSchema.parse(rawData); // throws if shape is wrong

// Or use safeParse to avoid throwing:
const result = RootObjectSchema.safeParse(rawData);
if (!result.success) {
  console.error(result.error.issues);
} else {
  console.log(result.data.username); // fully typed
}

Interfaces vs tipos: ¿Cuál debes usar?

avatar: z.string().nullable(), // was z.null()
bio: z.string().optional(),    // if the field might be absent

Los alias pueden representar formas de objetos en TypeScript, y para la mayoría de los casos de tipado de respuestas de API son intercambiables. Las diferencias prácticas:

Ambos interface y type Las interfaces pueden extenderse y combinarse

  • — útil si deseas ampliar un tipo base en varios archivos. El mezclamiento de declaraciones te permite añadir campos a una interfaz definida en otro lugar. Los alias de tipo son más flexibles
  • — pueden representar uniones, intersecciones, tuplas y tipos mapeados, lo que las interfaces no pueden. Los mensajes de error tienden a ser más claros con interfaces
  • — TypeScript expande los alias de tipo en los mensajes de error, lo que puede hacer que los errores profundamente anidados sean más difíciles de leer. Para formas de respuestas de API, cualquiera funciona. Elige

si anticipas extender el tipo; usa interface si necesitas semánticas de unión o intersección. La coherencia dentro de un repositorio es más importante que cuál eliges. type El flujo práctico

Aquí tienes un flujo que toma minutos en lugar de una tarde:

Obtén una respuesta real.

  1. Usa la pestaña de red de tu navegador, Postman o curl para capturar una respuesta real de una API. Cuanto más completa sea la muestra, mejor serán los tipos generados. Genera la interfaz de TypeScript.
  2. Pega el JSON en el . Copia el resultado en tu proyecto. Generador de Interfaces de TypeScript a partir de JSONGenera el esquema de Zod.
  3. Pega el mismo JSON en el . Copia ese resultado también en tu proyecto. Generador de esquemas Zod a partir de JSONRevisa los campos nulos y opcionales.
  4. Revisa el resultado generado para campos tipificados como literal o campos que podrían faltar. Actualiza esos campos a null Valida en el límite de la solicitud. string | null, .nullable(), o .optional() según sea necesario.
  5. Reemplaza cualquier por as YourType . Ahora el tipo está garantizado para coincidir, no solo asumido. YourSchema.parse() o safeParse()Ese es el ciclo completo — desde JSON crudo hasta seguridad en tiempo de compilación y garantías en tiempo de ejecución en unos minutos.

JSON a TypeScript: Generar interfaces automáticamente a partir de respuestas de API 2

¿Quieres eliminar publicidad? Adiós publicidad hoy

Instalar extensiones

Agregue herramientas IO a su navegador favorito para obtener acceso instantáneo y búsquedas más rápidas

añadir Extensión de Chrome añadir Extensión de borde añadir Extensión de Firefox añadir Extensión de Opera

¡El marcador ha llegado!

Marcador es una forma divertida de llevar un registro de tus juegos, todos los datos se almacenan en tu navegador. ¡Próximamente habrá más funciones!

ANUNCIO · ¿ELIMINAR?
ANUNCIO · ¿ELIMINAR?
ANUNCIO · ¿ELIMINAR?

Noticias Aspectos técnicos clave

Involucrarse

Ayúdanos a seguir brindando valiosas herramientas gratuitas

Invítame a un café
ANUNCIO · ¿ELIMINAR?