DEV Community

Blair McKee
Blair McKee

Posted on

Generate Types for Your GraphQL Schemas in 5 Minutes

I couldn't find one single article that actually included all the steps to do this, so here's the step-by-step guide I wish I had hours ago on how to generate TypeScript types for your Graphql schemas 🫠

  • Separate your queries out from your components (optional, but nice)
  • Appease Webpack and TypeScript
  • Install some packages and plugins
  • Codegen time!

Context

I'm building an app using GraphCMS (super awesome, by the way) but the only gotcha is it doesn't offer a plugin to export your schema types. Since I can't function without TypeScript, that was a big problem the second I tried to write mutations or generate static pages using my schemas.

Step 1

Move your queries to a directory where only your queries will live.

Why? Separation of concerns, you don't want to couple your business logic with your presentational components. Also, it'll make it easier to to write your codegen config file.

query Question {
    questions {
    prompt
    tags
    id
    answer {
        html
    }
    }
}
Enter fullscreen mode Exit fullscreen mode

Make sure each query is stored in its own individual .graphql file.

Step 2

If you're using Create React App or NextJS, you won't be able to compile at this point because webpack has no idea what a .graphql file is.

I'm using Next so this will end up in my next.config.js file, but if you're using CRA you'll want to follow these directions so webpack can parse your query files.

module.exports = {
  webpack: (config) => {
    config.module.rules.push({
      test: /\.(graphql|gql)$/,
      exclude: /node_modules/,
      loader: 'graphql-tag/loader',
    });
    return config;
  },
  webpackDevMiddleware: (config) => {
    return config;
  },
};
Enter fullscreen mode Exit fullscreen mode

By the way, I found these config steps in this awesome NextJS + GraphQL + TypeScript setup article 👏🏼

You'll also want to add types for these files so Typescript doesn't yell at you. Add this to your graphql.d.ts file at the root of your app.

declare module '*.graphql' {
  import { DocumentNode } from 'graphql';
  const Schema: DocumentNode;

  export = Schema;
}
Enter fullscreen mode Exit fullscreen mode

Step 3

Install a bunch of stuff.

I'm using yarn so swap out npm i for yarn add if you haven't joined the yarn bandwagon, yet.

yarn add graphql-tag
yarn add graphql
yarn add @graphql-codegen/cli
yarn add @graphql-codegen/typescript-operations
yarn add @graphql-codegen/typescript
Enter fullscreen mode Exit fullscreen mode

👆🏼 There's a lot of stuff here, so let's break it down.

  • graphql-tag -> is our webpack loader
  • graphql -> you probably installed this already, but this is going to be an essential package later for when you want to make queries
  • @graphql-codegen/cli -> this is an awesome CLI that helps you setup your codegen config
  • the rest are plugins for the aforementioned CLI To get it to work with TypeScript

Step 4

Once you've run all those scripts, we can finally codegen our types!

You can use the CLI to setup your config, but I prefer to do it manually (it's also quicker, tbh. I tried 3 different codegen CLI's and this manual way the fastest and least error prone).

Create a codegen.yaml file at the root of your app and start plugging in the link to your API schema and directories for your queries.

schema: 'http://my-graphql-api.com/graphql'
documents: './src/queries/*.graphql'
generates:
  graphql/generated.ts:
    plugins:
      - typescript
      - typescript-operations
Enter fullscreen mode Exit fullscreen mode

The documents value must be a folder where all your queries live and they must be stored inside files that end with .graphql, .ts, or .tsx.

Last but not least, we'll add a script to our package.json to run all this.

"scripts": {
    "codegen": "graphql-codegen"
}
Enter fullscreen mode Exit fullscreen mode

Now you can run yarn codegen and see your generated types! Happy coding, y'all ⚛

Top comments (2)

Collapse
 
brense profile image
Rense Bakker

If you cant or dont want to use webpack, you can use the loader from graphql.macro to load your graphql files:

import { loader } from 'graphql.macro';
const query = loader('./foo.graphql');
Enter fullscreen mode Exit fullscreen mode
Collapse
 
theblairwitch profile image
Blair McKee

oh! I just learned about babel macros! this is great, thank you!