Generate TypeScript types for your GraphQL operations

As we've previously seen by generating TypeScript types we can automatically create types based on your projects GraphQL API schema.

Let's take this a step further by generating types for GraphQL queries and mutations inside of your project.


Install the following dependencies to get started:

  • typescript
  • @graphql-codegen/cli
  • @graphql-codegen/client-preset
npm install -D typescript @graphql-codegen/cli @graphql-codegen/client-preset

Then inside package.json add to scripts a new command:

{
  "codegen": "graphql-codegen -r dotenv/config"
}

You'll notice above we're preloading dotenv/config which means we can use environment variables instead of committing our Grafbase API URL and API Key to source control.

Create .env in the root of your project and add your project API URL and API Key:

GRAFBASE_API_URL=
GRAFBASE_API_KEY=

Next inside of the project root, create the file codegen.ts and add your Grafbase API URL and API key:

import { CodegenConfig } from '@graphql-codegen/cli'

const config: CodegenConfig = {
  schema: {
    [process.env.GRAFBASE_API_URL]: {
      headers: {
        'x-api-key': process.env.GRAFBASE_API_KEY
      }
    }
  }
}

export default config

Now we've configured the location of the schema we can configure the files we want to generate, and the plugins we want to use.

We'll be using the client-preset to generate the folder gql in the root of our project. You can update this to output where you like.

import { CodegenConfig } from '@graphql-codegen/cli'

const config: CodegenConfig = {
  schema: {
    [process.env.GRAFBASE_API_URL]: {
      headers: {
        'x-api-key': process.env.GRAFBASE_API_KEY
      }
    }
  },
  generates: {
    './gql/': {
      preset: 'client',
      plugins: []
    }
  }
}

export default config

Finally, we'll want to ignore the warnings for no documents:

import { CodegenConfig } from '@graphql-codegen/cli'

const config: CodegenConfig = {
  schema: {
    [process.env.GRAFBASE_API_URL]: {
      headers: {
        'x-api-key': process.env.GRAFBASE_API_KEY
      }
    }
  },
  generates: {
    './gql/': {
      preset: 'client',
      plugins: []
    }
  },
  ignoreNoDocuments: true
}

export default config

We can now run the script codegen to generate the TypeScript types for the provided Grafbase API schema:

npm run codegen

At this point GraphQL Code Generator will generate types for the schema, but it doesn't yet know about any GraphQL operations — we'll change that next!

Inside your codegen.ts you can provide a glob for files that contain your GraphQL operations. We'll use the app directory in this example:

import { CodegenConfig } from '@graphql-codegen/cli'

const config: CodegenConfig = {
  schema: {
    [process.env.GRAFBASE_API_URL]: {
      headers: {
        'x-api-key': process.env.GRAFBASE_API_KEY
      }
    }
  },
  generates: {
    './gql/': {
      preset: 'client',
      plugins: []
    }
  },
  ignoreNoDocuments: true,
  documents: ['app/**/*.{ts,tsx}']
}

export default config

You'll notice here that we provide the glob to .{ts,tsx} files and not .{gql,graphql} like you may have been used to doing before with GraphQL Code Generator. You should now write GraphQL queries, mutations, and fragments inside files that use them.

You'll want to change the directory app if that's not where your pages/components are stored.

So that GraphQL Code Generator can correctly type any operations you will need to use the newly exported graphql function from the directory ./gql (or whatever you named it).

Inside of your application you will want to import graphql and pass your operation to it:

import { graphql } from '../gql'

const GetAllPostsDocument = graphql(/* GraphQL */ `
  query GetAllPosts {
    postCollection(first: 10) {
      edges {
        node {
          title
          published
          author {
            name
          }
        }
      }
    }
  }
`)

You can now run the codegen script to generate the types for your API and GraphQL operations:

npm run codegen

GraphQL Code Generator will now generate a TypedDocumentNode that you can pass to a client library that supports it so you have full type-safety.

You can use the --watch flag to watch for any changes instead of manually invoking codegen after every change:

{
  "codegen": "graphql-codegen -r dotenv/config",
  "watch": "graphql-codegen -r dotenv/config --watch"
}

That's it! — You now have TypeScript types for your API and GraphQL operations.

Build your next type-safe backend with Grafbase

Get early access to the Grafbase beta.