TypeScript, GraphQL Code Generation & Type Safety
Connect GraphQL schemas with TypeScript, generate strongly typed operations and resolver types, and build safer end-to-end GraphQL applications.
Why Use TypeScript with GraphQL?
GraphQL already provides a strongly typed schema, while TypeScript provides static typing inside the application. Combining the two can create a type-safe development experience from the API schema to server resolvers and client operations.
Without code generation, developers often write TypeScript interfaces manually for GraphQL responses. These manually maintained types can drift away from the actual schema.
GraphQL code generation solves this by deriving TypeScript types from the schema and operations.
Generating Types from a GraphQL Schema
A GraphQL code generation tool can inspect a schema and generate TypeScript representations of scalar types, object types, enums, input types, interfaces, unions, and resolver signatures.
For example, a GraphQL User type can become a TypeScript type. A GraphQL UserInput can become an input type, while resolver type definitions can describe the expected arguments, parent values, context, and return values.
This reduces repetitive type declarations and makes schema changes visible to the TypeScript compiler.
Generating Types from Queries and Mutations
Generating types only from the schema is not enough for client applications. A client operation usually selects only a subset of fields from an object.
For example, the schema may define 20 fields on User, while a particular query selects only id, name, and email. Operation-based code generation can produce a result type representing exactly that selection.
This prevents developers from accidentally assuming that fields exist in a response when they were not requested.
GraphQL Code Generation Workflow
A typical workflow starts with a GraphQL schema, followed by GraphQL documents containing queries, mutations, and fragments. A code generation tool reads these sources and produces TypeScript types or client-specific helpers.
The generated output should generally be treated as build artifacts rather than manually edited source code. When the schema or operations change, the generation step should run again.
Configuring GraphQL Code Generation
A code generation configuration normally specifies the GraphQL schema source, operation document locations, plugins, and output paths.
A project may generate different artifacts for different purposes. Server code may need resolver types, while a React client may need operation result types and typed document nodes.
The exact configuration depends on the chosen GraphQL code generation ecosystem and client architecture.
Example Generated Type Workflow
The following example illustrates the relationship between a GraphQL schema and generated TypeScript types.
Schema to TypeScript
type User {
id: ID!
name: String!
email: String!
}Type-Safe GraphQL Resolvers
Generated resolver types can make server development safer by typing the resolver parent value, arguments, context, and return value.
This is especially useful for large schemas where manually keeping resolver signatures synchronized with the schema becomes difficult. When a field changes from nullable to non-null or its arguments change, generated resolver types can expose the mismatch during compilation.
GraphQL Nullability and TypeScript
GraphQL nullability has a direct impact on generated TypeScript types. A field declared as String! should normally be represented as a non-null string, while String must allow null.
This distinction is important because TypeScript code should not blindly assume that nullable GraphQL fields always contain values.
Understanding the difference between optional properties and nullable values is also important when configuring code generation.
Custom Scalars and TypeScript Mappings
GraphQL custom scalars such as DateTime, JSON, or UUID require an application-level representation. Code generation tools can map these scalars to TypeScript types.
For example, a DateTime scalar might map to string when the API uses ISO-8601 strings, or to Date in a specific client-side representation. The mapping should match the actual runtime serialization behavior.
Check Your Understanding
Test your understanding of GraphQL code generation.
Why is operation-based TypeScript generation useful for GraphQL clients?