GraphQL Type System Explained
GraphQL has a rich type system that maps cleanly to TypeScript. Use the converter above to see how each GraphQL type translates to TypeScript interfaces, enums, and type aliases.
GraphQL to TypeScript Converter
Convert GraphQL SDL schemas to TypeScript interfaces, types, enums, and operations. Paste your schema and get typed code instantly.
// ── Scalars ──
export type DateTime = string;
// ── Enums ──
export enum UserRole {
ADMIN = "ADMIN",
EDITOR = "EDITOR",
AUTHOR = "AUTHOR",
READER = "READER",
}
// ── Types ──
/** A blog post */
export interface Post {
id: string;
title: string;
content: string;
slug: string;
published: boolean;
createdAt: string;
updatedAt?: string;
author: User;
tags: Tag[];
comments: Comment[];
}
export interface User {
id: string;
name: string;
email: string;
avatar?: string;
bio?: string;
posts: Post[];
role: UserRole;
}
export interface Comment {
id: string;
body: string;
author: User;
post: Post;
createdAt: string;
}
export interface Tag {
id: string;
name: string;
slug: string;
posts: Post[];
}
// ── Input Types ──
export interface CreatePostInput {
title: string;
content: string;
slug?: string;
published?: boolean;
tagIds?: string[];
}
export interface UpdatePostInput {
title?: string;
content?: string;
slug?: string;
published?: boolean;
tagIds?: string[];
}
// ── Operations ──
export interface Query {
/** Args: (limit: number, offset: number, published: boolean) */
posts: Post[];
/** Args: (id: string) */
post?: Post;
users: User[];
/** Args: (id: string) */
user?: User;
tags: Tag[];
}
export interface PostsArgs {
limit?: number;
offset?: number;
published?: boolean;
}
export interface PostArgs {
id: string;
}
export interface UserArgs {
id: string;
}
export interface Mutation {
/** Args: (input: CreatePostInput) */
createPost: Post;
/** Args: (id: string, input: UpdatePostInput) */
updatePost?: Post;
/** Args: (id: string) */
deletePost: boolean;
/** Args: (name: string, email: string, password: string) */
register: User;
}
export interface CreatePostArgs {
input: CreatePostInput;
}
export interface UpdatePostArgs {
id: string;
input: UpdatePostInput;
}
export interface DeletePostArgs {
id: string;
}
export interface RegisterArgs {
name: string;
email: string;
password: string;
}
4
Types
2
Inputs
1
Enums
0
Unions
0
Interfaces
1
Scalars
2
Operations
45
Fields
Press Ctrl+Enter to copy
Default Scalar Mappings
Object types
Object types are the most common. 'type User { id: ID!, name: String! }' becomes a TypeScript interface with the same fields. Non-null fields (!) become required properties, nullable fields become optional or have '| null'. Arrays like '[Post!]!' become 'Post[]'.
Input types
Input types define the shape of mutation arguments. 'input CreateUserInput { name: String!, email: String! }' generates a separate TypeScript interface. Inputs often have more optional fields than output types since you typically only send the fields you want to update.
Enums and unions
GraphQL enums like 'enum Status { ACTIVE, INACTIVE }' can become TypeScript enums or const objects (preferred for tree-shaking). Unions like 'union SearchResult = User | Post' become TypeScript union types: 'type SearchResult = User | Post'. Both preserve the type safety of the original schema.
Interfaces and scalars
GraphQL interfaces like 'interface Node { id: ID! }' become TypeScript interfaces that other types can extend. Custom scalars like 'scalar DateTime' need explicit TypeScript type mappings — DateTime typically maps to 'string', JSON to 'Record<string, unknown>', and Upload to 'File'.
Frequently Asked Questions
What is the difference between type and input in GraphQL?
'type' defines output shapes returned by queries/mutations. 'input' defines argument shapes sent by the client. They generate identical TypeScript interfaces but serve different purposes: types describe what the API returns, inputs describe what the client sends.
Should I use TypeScript enums or const objects for GraphQL enums?
Const objects (as const) are generally preferred because they tree-shake better, work with string comparisons, and don't generate runtime JavaScript enum objects. TypeScript enums are fine for smaller projects where tree-shaking isn't critical.
How do nullable and non-null types map to TypeScript?
In GraphQL, fields are nullable by default. 'name: String' means the value can be null. 'name: String!' means it's guaranteed non-null. In TypeScript, nullable fields can be represented as optional properties (name?: string) or explicit union types (name: string | null).
Related Convert Tools
OpenAPI to TypeScript
Convert OpenAPI 3.x and Swagger 2.0 specs to TypeScript interfaces and types with $ref resolution, allOf/oneOf/anyOf, enums, and API operation types
JSON to Zod Converter
Convert JSON or JSON Schema to Zod validation schemas with $ref resolution, allOf/oneOf/anyOf, enum, format constraints, and required/optional fields
TypeScript to JavaScript
Convert TypeScript to JavaScript — strip types, interfaces, enums, generics, and access modifiers to get clean JS output
JSON to SQL Converter
Convert JSON arrays to SQL CREATE TABLE and INSERT statements for PostgreSQL, MySQL, and SQLite with automatic type inference