Generador de GraphQL a TypeScript

Generador de GraphQL a TypeScript

Convierte esquemas SDL y consultas GraphQL en tipos, interfaces, enums y resolvers de TypeScript. Generación de código instantánea en el navegador sin configuración ni envío a servidores.

Plantillas
Ecosistema objetivo de codegen
Origen del esquema GraphQL (SDL / JSON)
Escalares rápidos:
Exportación lista para producción
12Nodes
AST Architecture
Object: 6Interface: 1Enum: 1Input: 1
83%Strict
Nullability Guard

High non-null strictness (safe against unexpected runtime undefined).

AST de esquema válido
/**
 * Strongly Typed GraphQL TypeScript Artifacts
 * Generated via ToolsAA In-Browser Codegen Engine [Regime: strict-modern]
 * 100% In-Browser AST synthesis - Zero server upload
 */

type Maybe<T> = T | null;

type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> };
type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> };

/** All Built-In & Custom GraphQL Scalars */
type Scalars = {
  DateTime: string;
};

type Scalars = {
  JSON: Record<string, unknown>;
};

type Scalars = {
  Money: number;
};

type ProductStatus = 'DRAFT' | 'ACTIVE' | 'ARCHIVED' | 'OUT_OF_STOCK';

type Node = {
  __typename?: string;
  readonly id: string;
  readonly createdAt: string;
  readonly updatedAt: string;
};

type MoneyAmount = {
  __typename?: 'MoneyAmount';
  readonly amount: number;
  readonly currency: string;
};

type ProductVariant = {
  __typename?: 'ProductVariant';
  readonly id: string;
  readonly sku: string;
  readonly title: string;
  readonly price: MoneyAmount;
  readonly inStock: boolean;
  readonly inventoryQuantity: number;
  readonly createdAt: string;
  readonly updatedAt: string;
};

type Review = {
  __typename?: 'Review';
  readonly id: string;
  readonly author: string;
  readonly rating: number;
  readonly comment: Maybe<string>;
  readonly metadata: Maybe<Record<string, unknown>>;
  readonly createdAt: string;
  readonly updatedAt: string;
};

type Product = {
  __typename?: 'Product';
  readonly id: string;
  readonly title: string;
  readonly slug: string;
  readonly description: Maybe<string>;
  readonly status: ProductStatus;
  readonly price: MoneyAmount;
  readonly variants: ReadonlyArray<ProductVariant>;
  readonly reviews: ReadonlyArray<Review>;
  readonly createdAt: string;
  readonly updatedAt: string;
};

type Query = {
  __typename?: 'Query';
  readonly product: Maybe<Product>;
  readonly products: ReadonlyArray<Product>;
};

type Mutation = {
  __typename?: 'Mutation';
  readonly createProduct: Product;
  readonly deleteProduct: boolean;
};

type CreateProductInput = {
  readonly title: string;
  readonly slug: string;
  readonly description?: Maybe<string>;
  readonly price: number;
  readonly currency?: Maybe<String = "USD">;
  readonly status?: Maybe<ProductStatus = DRAFT>;
};
Tipos12
Campos40
Enums1
Uniones0
Escalares3
Tiempo de ejecución< 1ms
Referencia técnica y guía de arquitectura

Generador GraphQL a TypeScript — Guía de referencia

Convierte esquemas SDL y consultas de GraphQL en tipos, interfaces, enums y resolvers de TypeScript. Generación de código instantánea en el navegador, sin configuración ni subida de datos al servidor.

Generador GraphQL a TypeScript — Guía de referencia — Arquitectura en memoria del lado del cliente y flujo de datos
Generador GraphQL a TypeScript — Guía de referencia — Arquitectura en memoria del lado del cliente y flujo de datos

Parámetros clave y controles

Fuente del esquema GraphQL (SDL vs. JSON de introspección)Documento de definición de esquema (entrada AST)

Texto estándar en Schema Definition Language (SDL) de GraphQL o respuesta de introspección serializada en JSON (objeto raíz __schema). Cumple con la gramática oficial de la especificación de GraphQL de octubre de 2021.

Por defecto: Schema Definition Language (SDL)
Estrategia de nulabilidad y opcionalidadModo de nulabilidad del compilador (Enum)

Mapea los campos no nulos (!) y nulables de GraphQL a expresiones de tipos de TypeScript. Controla si los campos nulables generan 'T | null', 'Maybe<T>' o propiedades opcionales 'field?: T' bajo strictNullChecks de TypeScript.

Por defecto: Maybe<T> = T | null | undefined
Paradigma de declaración de tiposSintaxis de emisión de tipos (Enum)

Define si los tipos Object de GraphQL se compilan como alias 'type' o declaraciones 'interface' de TypeScript. Los alias de tipo admiten uniones y acceso indexado; las interfaces permiten la fusión de declaraciones (declaration merging) en SDK extensibles.

Por defecto: type (alias de tipo)
Formato de compilación de enumsRepresentación de enums (Enum)

Controla si los enums de GraphQL se compilan como objetos nativos 'enum' en tiempo de ejecución de TypeScript o como uniones de literales de cadena ('ADMIN' | 'USER') optimizables mediante tree-shaking con diccionarios const auxiliares.

Por defecto: Unión de literales de cadena
Mapeo de escalares personalizados (ScalarMappingDictionary)Diccionario (Record<string, string>)

Resuelve escalares personalizados de GraphQL a tipos concretos de TypeScript. Mapeos por defecto: ID a 'string', Int a 'number', Float a 'number', String a 'string', Boolean a 'boolean', DateTime a 'string | Date'.

Por defecto: DateTime: string, JSON: Record<string, unknown>
Modificador inmutable / matriz de solo lectura (ReadonlyArray)Flag de inmutabilidad (Boolean)

Al activarse, inyecta el modificador 'readonly' en cada campo de objeto y envuelve todas las listas en 'ReadonlyArray<T>', forzando la inmutabilidad en tiempo de compilación para almacenes de estado como Redux y Zustand.

Por defecto: true

Consejos profesionales y mejores prácticas

Trampa universal de nulabilidad: campos nulables en GraphQL vs. undefined en TypeScript

En GraphQL, un campo de salida nulable sin signo de exclamación devuelve null explícito cuando no contiene datos, nunca undefined. En TypeScript, declarar 'field?: string' admite undefined pero rechaza el null explícito bajo strictNullChecks. Para tipos de respuesta de cliente, genera siempre 'field: Maybe<string>' (string | null) en lugar de 'field?: string' para evitar excepciones TypeError en tiempo de ejecución al acceder a cargas del servidor que contengan valores nulos.

Evita enums numéricos nativos: usa uniones de literales de cadena para eliminar código en runtime

El 'enum' nativo de TypeScript genera un objeto IIFE de búsqueda bidireccional en JavaScript que los empaquetadores modernos (Vite, Rollup, esbuild) no pueden eliminar mediante tree-shaking. En aplicaciones de cliente, generar 'type UserRole = "ADMIN" | "MEMBER"' junto con un array congelado con 'as const' elimina el 100 % del impacto en el bundle en tiempo de ejecución, ofreciendo idéntico autocompletado y un estrechamiento de tipos (type narrowing) más estricto.

Enmascaramiento de fragmentos con TypedDocumentNode frente a envoltorios genéricos de consulta

En lugar de emitir tipos de resultado de consulta monolíticos y realizar castings manuales en las respuestas de fetch, genera instancias de TypedDocumentNode<ResultType, VariablesType>. Los clientes modernos de GraphQL (Apollo Client 3.7+, urql y graphql-request) infieren automáticamente la estructura de los datos devueltos y las variables requeridas directamente desde el nodo del documento, sin necesidad de parámetros de tipo explícitos.

Distingue tipos de transporte en red de los modelos de dominio en memoria

Los escalares personalizados como DateTime, JSON y BigInt viajan por la red como cadenas JSON o números sin procesar. Si la generación de código mapea 'DateTime' al objeto 'Date' de JavaScript, una petición procesada con JSON.parse() estándar dejará el campo como string, provocando errores en tiempo de ejecución al invocar métodos de fecha (como date.toISOString() is not a function). Utiliza 'string' para los tipos de respuesta en red y reserva 'Date' para modelos de dominio procesados o transformadores de deserialización.

Problemas comunes y soluciones

⚠️Error del compilador de TypeScript TS2322: Type 'null' is not assignable to type 'undefined' en objetos de entrada generados

Los objetos de entrada (input objects) de GraphQL tratan los campos omitidos como undefined, mientras que un null explícito indica un reseteo o borrado intencional. Habilita exactOptionalPropertyTypes en tsconfig.json y configura la estrategia de entrada del generador para emitir 'field?: string | null' en los argumentos de entrada, diferenciando entre omitir una clave y enviar un payload con null explícito.

⚠️La profundidad de referencia circular supera los límites del compilador de TypeScript en esquemas recursivos anidados

Las estructuras de esquema autorreferenciadas (como Comment -> replies: [Comment!]! o Category -> children: [Category!]!) pueden desencadenar el error TS2589 de instanciación de tipos infinita. Soluciona esto emitiendo las definiciones de tipos como declaraciones 'interface' en lugar de alias 'type' recursivos anidados, aprovechando la resolución perezosa (lazy resolution) de propiedades de las interfaces en TypeScript.

⚠️Syntax Error: Unexpected token in JSON at position 0 al pegar resultados de introspección

Asegúrate de pegar el payload JSON completo que contenga la clave raíz '__schema' o 'data.__schema'. Si la consulta de introspección se extrajo con curl o Postman, elimina las cabeceras de respuesta HTTP o desescapa las comillas dobles escapadas antes de procesar el JSON.

⚠️Las directivas de Apollo Federation (@key, @external, @shareable) provocan errores de análisis por directivas desconocidas

El parser estándar de la especificación de GraphQL no incluye por defecto las directivas de esquema de Apollo Federation v1/v2. El generador incluye definiciones base para directivas de federación; asegúrate de activar la casilla 'Habilitar directivas de federación' o pega el bloque de definiciones estándar de directivas de Federation al inicio de tu SDL.

Preguntas frecuentes (FAQ)

¿Cómo se mapea la nulabilidad de GraphQL a campos opcionales o uniones con null en TypeScript?▼

En el SDL de GraphQL, los campos son nulables por defecto y solo son no nulos cuando se marcan con un signo de exclamación (!). En TypeScript con strictNullChecks, los campos no nulos (String!) se compilan como 'string', mientras que los nulables (String) se compilan como 'string | null' (o 'Maybe<string>'). Para los objetos de entrada (input), los campos nulables se convierten en propiedades opcionales ('field?: string | null'), ya que GraphQL permite omitir argumentos en consultas y mutaciones.

¿Deben compilarse los enums de GraphQL a enums de TypeScript o a uniones de literales de cadena?▼

Las uniones de literales de cadena ('type Status = "ACTIVE" | "INACTIVE"') son la opción recomendada para aplicaciones web modernas, ya que compilan a cero código JavaScript en tiempo de ejecución, permiten un tree-shaking perfecto y admiten literales de texto directos sin necesidad de importar el enum. Los enums nativos de TypeScript ('enum Status { Active = "ACTIVE" }') solo deben elegirse cuando se requiera reflexión de objetos en runtime, búsqueda inversa o integración con librerías heredadas.

¿Cuál es la diferencia entre la generación de tipos del esquema y la de tipos de operaciones del cliente?▼

La generación de tipos del esquema compila todo el esquema del backend de GraphQL (cada tipo, input, enum y signatura de resolver) en interfaces exhaustivas de TypeScript. La generación de tipos de operaciones del cliente examina documentos de consulta específicos del cliente, selecciona únicamente los subcampos solicitados (aplicando conjuntos de selección y fragmentos) y genera tipos de respuesta precisos y aplanados que coinciden exactamente con la carga útil JSON devuelta por esa consulta en particular.

¿Por qué el escalar ID de GraphQL se serializa como string o number en lugar de un tipo dedicado en TypeScript?▼

La especificación oficial de GraphQL define el escalar ID como un identificador único serializado como String, pero permite que los clientes envíen valores de cadena o entero como entrada. En consecuencia, el generador mapea ID a 'string' (para tipos de salida) o 'string | number' (para argumentos de entrada). Las aplicaciones que requieran seguridad de tipos estricta entre identificadores de diferentes entidades deben utilizar tipos nominales o branded types (por ejemplo, 'type UserId = string & { readonly __brand: unique symbol }').

Herramientas y utilidades relacionadas

Todas las herramientas →