Generate TypeScript Types from GraphQL

In this post, I want to explain something that tripped me up for a long time: how to generate TypeScript types from a GraphQL server.

"Wait, TypeScript types and GraphQL types are different??"#

They are! In fact, you even have types for your queries, which is extra confusing. Let me try to clarify.

So, in your GraphQL server you might expose a User object. User has fields like id, email, username, profileImageUrl etc. When your client consumes this API it is over HTTP -- but if we're using TypeScript, it would be nice to have TypeScript types that match the GraphQL types.

So again,

  • GraphQL is "protocol" and language with a definition.

  • TypeScript is a programming language

*and they both have their own, separate, types.

This post shows you how to generate TypeScript types from your GraphQL server. And it's super handy because not only is your code type-checked, but your editor will also help you autocomplete.

Generating GraphQL TypeScript Types by Hand (lol don't do this)#

At first, you might try writing these types by hand, but this will just drive you crazy to maintain by hand as your app grows.

However, in a large scale production application, there could be hundreds of GraphQL endpoints & types. Take a look at GitHub's v4 GraphQL API, no joke, there are almost 1,000 endpoints & types. Creating TypeScript definitions for those (by hand) would be a nightmare!

Not only that, a change in the server means you will have to find and update your TypeScript definitions over and over again. Ew.

Of course every GraphQL API already has types defined in the schema. Wouldn't be great if there is something that can translate GraphQL types into TypeScript automatically?

As you've probably predicted, there is.

Apollo CLI#

Ladies & gentleman, let me introduce to you, Apollo CLI.

The Apollo CLI is a robust command line interface that allows for a variety of different things such as schema validation, generate static types, and etc. And we'll use this tool to auto-generate TypeScript definitions from our GraphQL API. Here's how:

To use the Apollo CLI, we can install it globally with the following command:

There are two commands we are especially interested in:

  1. download our GraphQL schema and save a copy of it in our client

  2. auto generate the TypeScript definitions from our schema

We'll set up both of these steps as two separate script commands in our application's package.json file. We'll label these scripts codegen:schema and codegen:generate.

Downloading the Schema#

To download the schema, we'll need to run the apollo client:download-schema command and specify the options we would want. In our case, we'll specify the single minimum option we need - the endpoint and pass in the value of our local GraphQL endpoint (http://localhost:9000/api).

We'll run the newly created codegen:schema script in our command line.

After a brief period, we'll notice success messages that state Loading Apollo Project and Saving schema to schema.json.

If we look at the root of our client/ directory, we'll notice a schema.json file be generated that represents our entire GraphQL schema!

With the GraphQL schema available in our app, we can now look to generate the static types for the listings query and deleteListing mutation in our GraphQL API. This can be done with the Apollo CLI client:codegen command.

Generating the TypeScript Types#

We'll specify a few options as we set up the script.

The first option we'll add is the --localSchemaFile option, which is used to specify the path to the schema file in our client/ directory. Since the schema.json file is in the root of our project, the value for the --localSchemaFile option will be schema.json.

The second option we'll specify is the --includes option which is used to state the files that contain the GraphQL operations we'll want to generate static types for. In my case, all of my GraphQL requests live in TypeScript files within my src/ folder. There fore, I'll specify a value of src/**/*.tsx which entails looking through our entire src/ folder and for any files that have the .tsx file extension.

The final option we'll specify is the —-target option, which is required and allows us to specify which code generator we'd like to use. swift, flow, scala are all different options but in our case we're interested in the typescript option.

We'll have the above apollo command as part of the codegen:generate script command in our application.

We can now run the newly created codegen:generate command in our terminal.

Upon success, we'll see the Loading Apollo Project message followed by Generating query files with 'typescript' target - wrote 3 files.

By default, the Apollo code generator creates static typings for the GraphQL documents it finds in __generated__/ folders. For example:

If we take a look at one of these auto generated files, we can see TypeScript interfaces for the return data and input variables!

Get Up To Speed with Tinyhouse#

In Tinyhouse, you'll get up to speed with this whole stack really quickly. We've organized the course so that you can skip around if you just want to learn a specific part, but we also build the whole production-ready app if you want to walk through step-by-step. Check out Tinyhouse: a Fullstack React Masterclass