Never write TypeScript types for GraphQL schema by hand

Aleksey Kozin
Jan 5 · 4 min read
Image for post
Image for post

Why do we want to use TypeScript?

Modern software development best practices require programmers to write tons of code:

  • Business logic

Without tests, your system will be doomed to face well-known issues:

  • Teams spend most of their time fixing bugs and not adding new features

You need to write tons of code to be on top of your game. Don’t make your life harder. Never again write TypeScript types for GraphQL schema by hand.

TypeScript validates, that your program supports the current GraphQL schema. This adds an awesome layer of quality testing for both the front and back ends:

  • Your CI/CD can run TypeScript validation and Unit Tests on your repo and detect any schema cracks.

But writing TypeScript types by hand is a tedious task with fragile results.

Why do we want to automate TypeScript generation from GraphQL schema?

GraphQL allows to automatically generate TypeScript types from a schema file. This feature will:

Save your time. Each schema update should be manually validated and checked on errors. Even a small schema can be >1000 lines of TypeScript definitions. And don't forget that on a React frontend you will need to write Apollo React Hooks.

Protect you from human error. GraphQL specification is quite complex and has lots of details. You most likely know the difference between:

offers(input: OffersInput): [ProductOffer]!

and

offers(input: OffersInput): [ProductOffer!]!

But can you reliable validate each such (and dozens of more small) differences on each schema update?

Protect you from GraphQL specification or schema update. GraphQL language specification evolves with time: https://spec.graphql.org/

Your codebase will always be in sync with the latest GraphQL schema. This way you will be protected from an accidental deployment of a breaking change to production. How cool is that? With automatic TypeScript generation, your GraphQL schema becomes a single source of truth for the whole distributed system.

How to setup automatic TypeScript generation from a GraphQL schema

In this article I’m using a Monorepo project setup, e.g., all my packages and projects are stored in a single repo. This way a client app and a backend can have access to one physical copy of GraphQL schema. But you can store your projects wherever you want, just find a way to provide the same GraphQL schema file to your back and front ends.

If you are consuming a third-party API you can consume the current GraphQL schema directly from the endpoint. I will describe the process later.

I highly recommend using the GraphQL Code Generator package.

  • Install “devDependencies” to your package (ofc you may use different package versions and plugins)
“@graphql-codegen/cli” — is the main package, “@graphql-codegen/*” — are plugins
  • Add “graphql-codegen” command to your “package.json” scripts section.
Good points will be “build” or “postinstall” (will be automatically called on the package installation)
  • Create a “codegen.yml” in your package root. This file will provide configuration for your “graphql-codegen” command. Check codegen.yml documentation

“schema” — where the program should search for GraphQL schema files. In this case, our client “order-list-app” searches for a server GraphQL schema in a nearby monorepo package “order-list-backend”. However, if you are consuming a third-party API, then here you should put your URL endpoint.

“documents” — these files look like graphql schema but describe the client’s operations. GraphQL clients use “documents” to form graphql requests and may be omitted on the backend side.

“graphql_api_build/types_and_hooks.tsx” — where to put result

“plugins"— what code should be generated. In this example, I want TypeScript types + Apollo React Hooks. There are no hooks on the backend, so “typescript-react-apollo” plugin could be omitted on a backend.

  • And That's It! Use and enjoy the huge amount of types for free. They will test your system from top to bottom.

You should not commit the generated TypeScript files to git

The files will be compiled directly from the graphql schema after “yarn install” or “npm install”, there is no need to commit them. This way your GraphQL schema will be a single source of truth.

You should recompile the TypeScript types on each schema update

If you have updated the schema, you should call your “graphql-codegen” script, to recompile types. Don’t worry to forget it tho. Compiled files are not committed to the repo, CI/CD will recompile them from a scratch and catch the error. You can’t break production with this inconsistent state.

Conclusion

TypeScript code generation is easy to automate and to use. graphql-code-generator has 6k stars on github. This package is polished way above you can realistically write by hand.

With compiled types you will get:

  • Fewer bugs

GraphQL is not just “REST with less network traffic”. It’s a much deeper and profound technology.

Thank you for reading,

Your feedback in the comments is highly appreciated.

JavaScript In Plain English

New JavaScript + Web Development articles every day.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store