GraphQL to TypeScript

Paste a GraphQL schema in SDL form and get matching TypeScript declarations. type, input, and interface definitions become interfaces; enum becomes a string-literal union or a TypeScript enum; union becomes a union type; and custom scalars map to a type you choose. GraphQL's non-null (!) and list nullability are translated faithfully, so optional fields get ? and nullable values get | null. Parsed entirely in your browser.

schema.ts

How to use the GraphQL to TypeScript

Paste your schema definition language — the contents of a .graphql file — or load one. Each object-like definition (type, input, interface) becomes a TypeScript interface; enum and union become type aliases; and a custom scalar becomes an alias to the placeholder type you pick. Field arguments and directives are ignored, since they have no place in a data type.

The important detail is nullability, which GraphQL and TypeScript express in opposite directions. In GraphQL a field is nullable by default and a trailing ! marks it non-null; in TypeScript a field is required by default. So a non-null field id: ID! becomes id: string, while a nullable field name: String becomes name?: string | null — optional because the server may omit it, and | null because it may return null. List nullability nests correctly too: [Post!]! becomes Array<Post>, whereas [Post] becomes Array<Post | null> | null.

GraphQL SDL and the TypeScript mapping

GraphQL's Schema Definition Language is the human-readable form of a schema: it lists the object types, input types, interfaces, enums, unions, and scalars that make up an API's type system. Because GraphQL is strongly typed, the SDL is a precise contract — which makes it an ideal source for generating client-side TypeScript so your code shares the server's vocabulary exactly.

The built-in scalars map cleanly: Int and Float become number, String and ID become string, and Boolean becomes boolean. Object types and interfaces become interfaces with the same field names. An enum is best represented as a string-literal union ("ADMIN" | "EDITOR"), which gives you autocompletion and exhaustiveness without runtime overhead, though a real TypeScript enum is available if your codebase prefers it. A union becomes a TypeScript union of its member types. Custom scalars like DateTime or JSON have no built-in TypeScript equivalent, so you choose how to represent them — string is the pragmatic default, unknown the safest, and any the loosest.

The subtle part is nullability. GraphQL fields are nullable unless annotated with !, the inverse of TypeScript where members are required unless marked ?. Mapping a nullable field to ?: T | null captures both facts: the field can be absent from a partial response and can carry an explicit null. This matches what real GraphQL clients send and what code-generators like GraphQL Code Generator produce, so the output drops into a typed client without surprises.

Common use cases

  • Typed GraphQL clients. Generate model interfaces for a hand-rolled client without a full codegen pipeline.
  • Quick prototyping. Turn a draft schema into TypeScript to sketch UI components against real shapes.
  • Schema review. Read an unfamiliar GraphQL API as TypeScript to grasp its data model fast.
  • Shared types. Produce a starting point for a types package consumed across front-end and BFF code.

Frequently asked questions

Which SDL definitions are supported?

type, input, interface, enum, union, and scalar. Field arguments, directives, and default values are parsed and ignored because they are not part of the resulting data type. Query, Mutation, and Subscription are treated like any other object type.

How is GraphQL nullability translated?

A non-null field (Type!) becomes a required TypeScript property. A nullable field (no !) becomes optional with | null, since the value may be absent or explicitly null. List item nullability nests correctly, so [Post!]! is Array and [Post] is Array | null.

What happens to custom scalars like DateTime?

They have no native TypeScript equivalent, so each becomes a type alias to the placeholder you select — string by default, or unknown / any. You can then refine those aliases by hand if a scalar serialises to something more specific.

Should I use a union or a TypeScript enum for enums?

String-literal unions are usually better: they are erased at compile time, work well with exhaustiveness checks, and match JSON values directly. A real TypeScript enum is offered for teams whose conventions rely on it. The choice is a single toggle.

Is this a full GraphQL Code Generator replacement?

No. It converts the schema types, which is the common need. It does not generate typed hooks, operation result types, or fragment types from your queries — for that, use GraphQL Code Generator. The interfaces here pair well with such tooling or stand alone.