Skip to Content
02 Core ConceptsGenerated Types

Generated Types

When Zeus generates code from your GraphQL schema, it creates a comprehensive TypeScript module with all the types and functions you need for type-safe GraphQL operations.

What Gets Generated

Zeus generates a single index.ts file (or custom path) containing:

  1. GraphQL Types - All schema types as TypeScript
  2. Chain - Simple query/mutation client
  3. Thunder - Custom fetch client
  4. Selector - Reusable field selections
  5. Zeus - Low-level query builder
  6. Type Utilities - Helper types for advanced usage

Generated File Structure

// Auto-generated by Zeus // ===== Schema Types ===== export type ValueTypes = { Query: { user: [{ id: string }, ValueTypes['User']]; posts: ValueTypes['Post'][]; }; User: { id: boolean; name: boolean; email: boolean; posts: ValueTypes['Post'][]; }; // ... more types }; export type ModelTypes = { Query: { user: ModelTypes['User']; posts: ModelTypes['Post'][]; }; User: { id: string; name: string; email: string; posts: ModelTypes['Post'][]; }; // ... more types }; // ===== Client Functions ===== export const Chain: (url: string, options?: any) => ChainClient; export const Thunder: (fn: any) => ThunderClient; export const Selector: <T extends keyof ValueTypes>(key: T) => SelectorFunction<T>; export const Zeus: ZeusFunction; // ===== Type Utilities ===== export type GraphQLTypes = /* ... */; export type InputType<T> = /* ... */; export type ScalarDefinition = /* ... */;

ValueTypes

ValueTypes represent the structure for building queries. Each field is either true/false or nested selections:

type ValueTypes = { User: { id: boolean; // Scalar field - select with true name: boolean; posts: ValueTypes['Post'][]; // Nested type - select subfields friends: [ { first?: number }, // Arguments ValueTypes['User'][], // Return type ]; }; };

Usage in Queries

// Using ValueTypes structure const result = await chain('query')({ user: [ { id: '123' }, // Arguments { id: true, // Select scalar name: true, posts: { // Select nested fields title: true, content: true, }, }, ], });

ModelTypes

ModelTypes represent the return types of queries - actual data shapes:

type ModelTypes = { User: { id: string; // Actual TypeScript type name: string; email: string; posts: ModelTypes['Post'][]; }; Post: { id: string; title: string; content: string; author: ModelTypes['User']; }; };

Usage for Type Annotations

import { ModelTypes } from './zeus'; // Type function parameters function displayUser(user: ModelTypes['User']) { console.log(user.name); } // Type component props type UserCardProps = { user: ModelTypes['User']; posts: ModelTypes['Post'][]; };

GraphQLTypes

A union of all schema types with full metadata:

export type GraphQLTypes = { Query: { __typename: 'Query'; user: GraphQLTypes['User']; posts: GraphQLTypes['Post'][]; }; User: { __typename: 'User'; id: string; name: string; email?: string | null; // Nullable fields }; // ... includes enums, inputs, interfaces, unions };

Usage

import { GraphQLTypes } from './zeus'; // Extract specific types type User = GraphQLTypes['User']; type QueryType = GraphQLTypes['Query']; // Use in generic functions function processEntity<T extends keyof GraphQLTypes>(type: T, data: GraphQLTypes[T]): void { // Fully typed based on schema }

Input Types

Input types for mutations and arguments:

export type InputTypes = { CreateUserInput: { name: string; email: string; age?: number | null; }; UpdateUserInput: { id: string; name?: string | null; email?: string | null; }; UserFilter: { role?: 'ADMIN' | 'USER' | null; active?: boolean | null; }; };

Usage

import { InputType, GraphQLTypes } from './zeus'; // Extract input type type CreateUserInput = InputType<GraphQLTypes['CreateUserInput']>; // Type-safe input creation const input: CreateUserInput = { name: 'Zeus', email: 'zeus@olympus.com', age: 3000, }; // Use in mutation const result = await chain('mutation')({ createUser: [{ input }, { id: true, name: true }], });

Enum Types

Enums are generated as TypeScript unions:

export type Enum = { UserRole: 'ADMIN' | 'USER' | 'MODERATOR'; PostStatus: 'DRAFT' | 'PUBLISHED' | 'ARCHIVED'; OrderStatus: 'PENDING' | 'COMPLETED' | 'CANCELLED'; };

Usage

import { ModelTypes } from './zeus'; // Type-safe enum usage const role: ModelTypes['UserRole'] = 'ADMIN'; // ✅ const invalid: ModelTypes['UserRole'] = 'INVALID'; // ❌ TypeScript error // In queries const result = await chain('query')({ users: [ { role: 'ADMIN', // Type-checked against schema }, { name: true, role: true, }, ], });

Scalar Types

Custom scalars with type mappings:

export type Scalars = { String: string; Int: number; Float: number; Boolean: boolean; ID: string; DateTime: string; // Custom scalar JSON: any; // Custom scalar Upload: File; // Custom scalar };

Custom Scalar Configuration

// zeus.config.js module.exports = { scalars: { DateTime: 'string', JSON: 'Record<string, any>', Upload: 'File', }, };

Chain Client Type

The main query/mutation client:

export type ChainClient = { query: <Z extends ValueTypes[Operation]>( o: Z | ValueTypes[Operation], ops?: Operations, ) => Promise<InputType<GraphQLTypes[Operation], Z>>; mutation: <Z extends ValueTypes[Operation]>( o: Z | ValueTypes[Operation], ops?: Operations, ) => Promise<InputType<GraphQLTypes[Operation], Z>>; subscription: <Z extends ValueTypes[Operation]>( o: Z | ValueTypes[Operation], ) => SubscriptionClient<InputType<GraphQLTypes[Operation], Z>>; };

Usage

import { Chain } from './zeus'; const chain = Chain('https://api.com/graphql'); // Fully typed operations const queryResult = await chain('query')({ /* ... */ }); const mutationResult = await chain('mutation')({ /* ... */ }); const subscription = chain('subscription')({ /* ... */ });

Thunder Client Type

Custom fetch client with full control:

export type ThunderClient = { query: <Z extends ValueTypes[Operation]>( o: Z | ValueTypes[Operation], ) => Promise<InputType<GraphQLTypes[Operation], Z>>; mutation: <Z extends ValueTypes[Operation]>( o: Z | ValueTypes[Operation], ) => Promise<InputType<GraphQLTypes[Operation], Z>>; }; export const Thunder: (fn: (query: string, variables: Record<string, any>) => Promise<any>) => ThunderClient;

Usage

import { Thunder } from './zeus'; const thunder = Thunder(async (query, variables) => { // Custom fetch implementation return data; }); // Same typed interface as Chain const result = await thunder('query')({ /* ... */ });

Selector Type

Reusable field selections:

export type SelectorFunction<T extends keyof ValueTypes> = (selection: ValueTypes[T]) => ValueTypes[T]; export const Selector: <T extends keyof ValueTypes>(key: T) => SelectorFunction<T>;

Usage

import { Selector } from './zeus'; // Create typed selector const userFields = Selector('User')({ id: true, name: true, email: true, }); // Reuse in queries const result = await chain('query')({ user: [{ id: '123' }, userFields], users: [{ first: 10 }, userFields], });

Type Utilities

InputType

Extracts the return type based on selection:

import { InputType, GraphQLTypes, ValueTypes } from './zeus'; type UserSelection = { id: true; name: true; posts: { title: true }; }; // Infers: { id: string; name: string; posts: Array<{ title: string }> } type UserResult = InputType<GraphQLTypes['User'], UserSelection>;

$ (Variable Function)

Type-safe variable declarations:

import { $ } from './zeus'; // Generated function for variables const result = await chain('query')({ user: [ { id: $('userId', 'ID!'), // Type-safe variable }, { name: true, }, ], })({ userId: '123', // Must match variable type });

Re-generating Types

When your schema changes, regenerate types:

# Regenerate from schema file zeus schema.graphql ./src/zeus # Regenerate from URL zeus https://api.com/graphql ./src/zeus # Watch mode zeus schema.graphql ./src/zeus --watch

Import Patterns

Common Imports

// Core functionality import { Chain, Thunder, Selector } from './zeus'; // Type utilities import { ModelTypes, GraphQLTypes, InputType } from './zeus'; // Variable function import { $ } from './zeus'; // Everything import * as Zeus from './zeus';

Type-Only Imports

// For type annotations only import type { ModelTypes, GraphQLTypes } from './zeus'; function processUser(user: ModelTypes['User']) { // ... }

Generated Code Size

Zeus generates optimized code:

  • Small schemas: ~10-50KB
  • Medium schemas: ~50-200KB
  • Large schemas: ~200KB-1MB

The generated file is tree-shakeable - unused types don’t affect bundle size.

Type Safety Benefits

1. Schema Sync

Types are always in sync with your schema:

// If schema changes, TypeScript errors immediately const result = await chain('query')({ user: [ { id: '123' }, { removedField: true, // ❌ TypeScript error newField: true, // ✅ Available after regenerating }, ], });

2. Autocomplete

Full IDE autocomplete support:

await chain('query')({ user: [ { id: '123' }, { // IDE suggests all available fields name: true, // Ctrl+Space shows: email, posts, friends, etc. }, ], });

3. Refactoring

Safe refactoring across your codebase:

// Rename a field in schema // All usage sites show TypeScript errors // Find and fix all usages before running

Best Practices

1. Version Control

Commit generated files to track schema changes:

git add src/zeus/index.ts git commit -m "Update Zeus types for schema v2.1"

2. CI/CD Integration

Regenerate types in CI to detect schema drift:

# .github/workflows/ci.yml - name: Generate Zeus types run: zeus https://api.com/graphql ./src/zeus - name: Check for changes run: git diff --exit-code src/zeus/

3. Documentation

Document custom scalar mappings:

/** * Custom scalar types: * - DateTime: ISO 8601 string * - JSON: Any valid JSON value * - Upload: File object for multipart uploads */ import { Scalars } from './zeus';

Next Steps

Write Your First Query →

Last updated on