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:
- GraphQL Types - All schema types as TypeScript
- Chain - Simple query/mutation client
- Thunder - Custom fetch client
- Selector - Reusable field selections
- Zeus - Low-level query builder
- 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 --watchImport 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 runningBest 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
- Basic Queries - Start writing queries
- Variables - Using type-safe variables
- Selectors - Reusable selections