The Next Generation of GraphQL and TypeScript

Rate this content
Bookmark

New features in TypeScript that can improve our GraphQL workflow.

22 min
02 Jul, 2021

Video Summary and Transcription

The CTO of the Guild discusses the importance of keeping the GraphQL schema and TypeScript code in sync. They introduce GraphQL Cogen, a tool that generates TypeScript types and code to improve developer experience and type safety. The tool also generates ready-to-use React hooks based on Apollo Client and supports multiple languages and integration with various tools. They also discuss the introduction of Type Document Node, which generates a document node from GraphQL operations. They mention the new string manipulation features in TypeScript 4.1 and the ability to parse GraphQL type definitions with a lexer. They express the need for community help to overcome limitations in TypeScript with parsing complex and multiline strings.

Available in Español

1. Introduction to GraphQL and TypeScript Integration

Short description:

I'm Lhothan, the CTO of the Guild, a group of open source developers focused on GraphQL and TypeScript integration. Keeping the GraphQL schema and TypeScript code in sync is crucial to reduce runtime errors. GraphQL Cogen is a flexible tool that generates TypeScript types and code to improve developer experience and type safety. Let's dive into the most popular plugins, starting with TypeScript, which generates types based on the GraphQL schema and operations. We also generate code, like the TypeScript React Apollo plugin.

Hi, everyone. My name is Lhothan. I am the CTO of a group called the Guild. We're a group of open source developers mainly focused on GraphQL and its ecosystem. I'm here today to talk with you about GraphQL, TypeScript, the integration of the two, and tooling around it. And also a bit about the next generation of TypeScript and GraphQL integration.

So, let's start with the basics. Why do we even need this kind of integration? Each language has its own type system. GraphQL has its own type system where you define your GraphQL schema. It's called SDL and there is TypeScript which has its own type system. So, while writing your GraphQL schema, you need to keep in sync your GraphQL SDL where you define the actual schema and your TypeScript code where you write your actual implementation in resolvers. You can either do it manually and keep it in sync manually or you can use tooling for that. This is what I'm going to discuss in this case.

Keeping the two type systems in sync is very important because, consider a field that you have removed or added to your GraphQL schema, it needs to be reflected in the TypeScript code. So keeping this two in sync is important and will probably reduce most of your runtime errors related to GraphQL and TypeScript. So a few years ago I had issues with GraphQL and TypeScript, so I started with a small open source called GraphQL Cogen. This was four years ago and today we have a huge community and we're not generating only TypeScript it also flows C Sharp, Java much more, and we're generating more than just types, we're generating like an actual code that can help you to improve your developer experience and your type safety. Cogen is a very flexible tool you can write your own plugins and configure the output hook into the generation process and add your own code so it's pretty cool. I'm going to talk a bit about the most popular plugins that we have today that are related to TypeScript.

So the first one is TypeScript, the one that I mentioned before. This plugin just generates TypeScript types out of your GraphQL schema and this seems very similar because the type systems are kind of similar and we aim to generate code in TypeScript that is similar as possible to the GraphQL schema. But GraphQL schema isn't all. We also have queries mutations and everything that involves a selection set which is one of the most powerful features of GraphQL, the ability to choose fields and select exactly what you need and not more than that. So given the fact that you can choose the fields it means that your types are kind of dynamic and based on your selection of fields. So we are also generating types based on your GraphQL operations. So when you use it in your code you'll have fully typed safety. But this is only types. We're also generating more. As I said we're generating code. So here is a small example for another plugin called TypeScript React Apollo.

2. GraphQL Cogen Plugin Features

Short description:

The plugin generates ready-to-use React hooks based on Apollo Client and your operations. It pre-compiles the GraphQL operations and creates hooks based on the operation name. No manual type specification is needed, as types are burned into the generated hooks. The tool also generates a complete Resolvers signature, utilities for various frameworks, and supports multiple languages and integration with various tools. Give it a try with the live demo on our website.

And this plugin generates ready-to-use React hooks based on Apollo Client and on your operations. So it basically takes your GraphQL operations, pre-compiles those and creates ready-to-use hooks based on your operation name. So when you use it in your code, all you need to do is just to import the hook, provide your variables and then use the data.

And the idea is that we are burning the types into the generated hooks. So you don't need to specify manually types or anything like that. You just get autocomplete and type validation for the variables and the result type. So this is pretty cool. As I said, we're not generating just types and that, we're generating more.

There is Resolvers signature. So if you are a backend developer writing your GraphQL schema and implementation, you can generate a complete Resolvers signature out of your schema and integrate your own model types into that signature. We're generating a few utilities for Apollo Client, but not only, also for Oracle, GraphQL request, Vue, Stencil, Angular, whatever, you name it. And it's not only JavaScript and TypeScript, we're also generating more for more languages, and we're integrating basically with every tool that's available on this kind of ecosystem. So, you can use it with Webpack and with Gatsby and Next.js. And recently we introduced a new plugin for React query, if you're using it. So, give it a try, we have a very nice live demo on our website, you can just try it and see what is the output based on the input which you can just change or add. So, give it a try.

3. Introduction to Type Document Node

Short description:

Recently, we introduced a new concept and plugin in GraphQL Cogent called Type Document Node. It generates a document node from your GraphQL operation, including the types of the result and variables. If your client library supports typed document node, you can precompile your operations and get type safety and auto-completion. By merging the trees into a single object, TypeScript inference automatically detects types based on the document. Type document node is supported by GraphQL.js, Apollo Client 3, and Oracle. Additional libraries are supported through patches.

So, let's move to the next topic. Recently we introduced a new concept and a plugin in GraphQL Cogent called Type Document Node. So, basically what we're doing here, we're taking your GraphQL operation and we're generating a document node out of it, which is just an object representation of the GraphQL operation, nothing more than that, but what we're adding is the types of the result and the types of the variables burned into that object.

So, if you are using a client library that supports a typed document node, you can just precompile your GraphQL operations into a document node and just use it with your library and you don't need to specify anything else. Like you don't need to add types, you don't need to explicitly set the generics or something like that. You can just use the types as is and you'll get type safety on your variables and on your result, but also you'll get auto-completion based on the selection set that you chose and the fields that you wanted to use. So, this is pretty awesome.

So, if you wanted to know how it works. So, if you are not using typed document node, what we're generating for you today is a separate type for the result type of the operation, a separate type for the variables of that operation and a document node. As I said, it's just a compiled version of your GraphQL query. But these three are separate. Each one of them is defined separately. And when you use it, you need to specify two types and the object of the document itself. This might be an issue because using it like that means that if you'll get the type wrong, you won't catch it during development and you might get it only on runtime where it's too late.

So, we're thinking of how we can avoid this kind of explicitly set types. So, what we did is we took that document node. We took that type that we generated for the result type and the type for the variables. And we just merged all of the trees together into a single object. And the idea is that we're using TypeScript inference to automatically detect the types based on the document that you are passing. So, if you're using a library that supports type document node, all you need to do is just provide your GraphQL operation. You'll just get automatic types and auto-completion based on that operation. So, this is pretty awesome. And here, there are no, there is no place for mistakes, because you don't need to specify types manually or anything else. Just use it and it will be typed.

So, at the moment, type document node is supported directly from GraphQL.js. The type itself is part of the GraphQL.js implementation, so you can just use it from there. And this is gradually, becomes the standard for this kind of integration. Apollo Client 3 and Oracle adopted it and they are now using it and if you're using type document node, all you need to do is just specify it and the types will be inferred automatically. If you're not using those libraries, you can just go to the type document node repository, where you can see a list of additional plugins, additional libraries that we support. You can just use a patch that we provide and it will add support for those libraries until they will support it.

4. TypeScript 4.1 String Manipulation

Short description:

In TypeScript 4.1, you can manipulate string types at the compiler level. By defining specific structures and using TypeScript inference, you can extract and manipulate substrings, validate structures, and more. This powerful feature allows you to convert GraphQL SDL strings into types during compiler transpilation.

So far with type document node, my next topic for today is the next version of TypeScript, which is TypeScript 4.1 and the new awesome feature that it has. In this version of TypeScript, you are going to be able to use strings and do manipulation for those string at the level of this TypeScript compiler. This sounds a bit vague, I know, but think of taking string types that you define on TypeScript, like you see here, and just do manipulations for it at the level of your TypeScript compiler.

Here, for example, we define a type with the string world, and then we have a new type with greeting, and we just concat the string, and we have a new type with that output. So this is simple, but we can do much more with it. Let's take this one, for example. At this example, I defined a new type called statement, and it just has a string. I also defined a new helper type called extract name, and this type is kind of sophisticated. What it does, it takes the string, any string, and it tries to extract a specific structure out of it. So in this case, what we're doing is looking for a structure that starts with hello and then some name and then the rest of the string. We're using here TypeScript inference to extract the name. So basically, we're saying if this string matches this structure exactly, give me that name. Otherwise, just return never, which is our way to say it didn't work.

So let's say that I'm using this helper with my string here. The extracted type as you can see is my name, which is pretty cool. And this is all done at the level of the compiler. So we can do strings manipulations and extract some kind of like substrings and even detect structure, do validations. So this is pretty cool, but this is a simple string. We can do even more. Let's take this example. In this example, as you can see, I took the same string, but I added some more logic to that helper. So now extract name instead of just looking for a specific structure, it's looking for a more dynamic flow. So we're using inference to extract the greeting and then we expect a space and then the name and then a comma and then a space and then the question. Instead of just returning what we found, we can return a type, a new type script type that contains this. For example in this specific string we're going to get a splitted version of my string. So here we can see I have a name which is my name and greeting which is the actual greeting and the question, and this is like a type script type that we can use. As I said all of that is happening at the compiler level and we can take any string and apply any set of rules. So any string that follows a standard or a specific structure that is well defined can be put here and we can write the rule for extracting whatever inside. This is mind-blowing because as of today what we're doing with TypeScript and GraphQL, we're taking the GraphQL, converting it to AST, and then we take this AST and generate code and this code is later being loaded. But if we can take the GraphQL SDL as a string and just convert it as is into a type in real time during the compiler transpilation of the code.

5. Parsing GraphQL Type Definitions with Lexer

Short description:

You can take any GraphQL string and create the representing types of it on the fly. I wrote a basic GraphQL lexer to break the string into small pieces and parse it into the document node. By understanding the links between the pieces, we can create types on the fly at the compiler level. I re-implemented the GraphQL JS lexer in TypeScript helpers to parse type definitions and validate the language.

So this is mind-blowing because you can take any GraphQL string and create the representing types of it on the fly. So I took some time and I wrote a very basic GraphQL lexer. So as I said, GraphQL is structured. It's a structured language. We have this type system and we have the exact structure that defines the language and the components that are in it. So it's built as pieces as a small pieces that link to each other. This kind of representation is called lexer.

So what basically happens when you call GraphQL dot parse on a string, GraphQL takes the string, breaks it into a lot of small pieces and then takes those pieces and parses it into the actual document node and do validations on it. So if we take for example this simple query, simple type definition in GraphQL, let's try to break it into pieces. If we just try to understand what are the actual pieces here. So we have a type, the keyword type, and then another word, and then we have a brace here, and then we have another all of those are well defined in the GraphQL, let's call it dictionary because this defines how each sentence in the GraphQL language is structured. So in our case, this is how it will look like we have this how GraphQL will break it to pieces. So thinking of this new feature in TypeScript and GraphQL, we can basically take this kind of string and on the fly, convert it to the representation of the type. So if we can break it to pieces, like each piece on its own and understand the links between them, we can eventually be at a place where we can take a string that contains a GraphQL definition, it could be either a type or an operation, and create types on the fly on the compiler level.

So, I did a small example for how it's really working. What I did is, I took the implementation of the original GraphQL JS lexer and tried to re-implement it in TypeScript helpers. The idea behind it is to be able to define a GraphQL lexer that knows how to parse type definition on runtime and do this validation of the actual language. So what happens here is I took this string that defines a GraphQL type definition and I created a TypeScript helper called parse-graphql-lexer. And basically, what it does, it just looks for specific characters in the string level and it tries to break it to pieces. Each piece just points to the next one. This is how the original GraphQL lexer works. I was just trying to re-implement it with the type system. So as you can see here, I'm just looking for specific tokens that are known for us and are valid in the GraphQL language. And what I'm doing here, I'm trying to extract each one and then I'm moving to the next one. So in this case, we start with the beginning of the string and then here, as you can see in the result, we have a name. This type word is just a name for the lexer part because it's not parsed yet. So what we're doing, we just name it. And then I move into the next one, and as you can see here, we start with the name, name and then brace and this is fairly like a very long type definition because our goal is to be able to parse that into a structure that later can be used. So this is just a proof of concept. And the idea here was to take the very basic string and parse it into pieces that are understand.

6. Parsing GraphQL Strings and Seeking Community Help

Short description:

We can convert graphical strings into types on the fly, parse graphical schemas and operations dynamically, and create resolver signatures. However, there are limitations in TypeScript with parsing complex and multiline strings. We're actively seeking community help to overcome these limitations and improve the TypeScript and GraphQL ecosystem.

This is just a basic example of how we can take the graphical string and convert it into a type on the fly. But actually, there is more. If we're able to understand the structure from a graphical string, we can parse graphical schemas on the fly. We can understand graphical operations on the fly. And basically, take graphical strings and make it available for use within the TypeScript language.

So if we'll be able to understand the complete structure of a string, we can even have like a resolver signature that is typed on the fly. And actually, much more. So at the moment, this is just a proof of concept as I said. Our goal is to have more than that. But we need the help of the community.

At the moment, there are a few limitations at the level of TypeScript. We can't really parse very complicated strings and we can't really parse and deal with multiline strings that has white spaces. So we're trying to find ways to solve all that and make the TypeScript and GraphQL ecosystem much better. So if you're having ideas and this is something that interests you, feel free to ping us and maybe we can work together. So that's it for me. I hope that this talk was interesting for you. If you're having any questions, feel free to ping me or anyone from the guild on the discord channel.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

GraphQL Galaxy 2021GraphQL Galaxy 2021
32 min
From GraphQL Zero to GraphQL Hero with RedwoodJS
Top Content
We all love GraphQL, but it can be daunting to get a server up and running and keep your code organized, maintainable, and testable over the long term. No more! Come watch as I go from an empty directory to a fully fledged GraphQL API in minutes flat. Plus, see how easy it is to use and create directives to clean up your code even more. You're gonna love GraphQL even more once you make things Redwood Easy!
Vue.js London Live 2021Vue.js London Live 2021
24 min
Local State and Server Cache: Finding a Balance
Top Content
How many times did you implement the same flow in your application: check, if data is already fetched from the server, if yes - render the data, if not - fetch this data and then render it? I think I've done it more than ten times myself and I've seen the question about this flow more than fifty times. Unfortunately, our go-to state management library, Vuex, doesn't provide any solution for this.For GraphQL-based application, there was an alternative to use Apollo client that provided tools for working with the cache. But what if you use REST? Luckily, now we have a Vue alternative to a react-query library that provides a nice solution for working with server cache. In this talk, I will explain the distinction between local application state and local server cache and do some live coding to show how to work with the latter.
React Day Berlin 2023React Day Berlin 2023
21 min
React's Most Useful Types
We don't think of React as shipping its own types. But React's types are a core part of the framework - overseen by the React team, and co-ordinated with React's major releases.In this live coding talk, we'll look at all the types you've been missing out on. How do you get the props type from a component? How do you know what ref a component takes? Should you use React.FC? And what's the deal with JSX.Element?You'll walk away with a bunch of exciting ideas to take to your React applications, and hopefully a new appreciation for the wonders of React and TypeScript working together.
Vue.js London 2023Vue.js London 2023
30 min
Stop Writing Your Routes
The more you keep working on an application, the more complicated its routing becomes, and the easier it is to make a mistake. ""Was the route named users or was it user?"", ""Did it have an id param or was it userId?"". If only TypeScript could tell you what are the possible names and params. If only you didn't have to write a single route anymore and let a plugin do it for you. In this talk we will go through what it took to bring automatically typed routes for Vue Router.
TypeScript Congress 2023TypeScript Congress 2023
31 min
Making Magic: Building a TypeScript-First Framework
I'll dive into the internals of Nuxt to describe how we've built a TypeScript-first framework that is deeply integrated with the user's IDE and type checking setup to offer end-to-end full-stack type safety, hints for layouts, middleware and more, typed runtime configuration options and even typed routing. Plus, I'll highlight what I'm most excited about doing in the days to come and how TypeScript makes that possible not just for us but for any library author.

Workshops on related topic

React Advanced Conference 2021React Advanced Conference 2021
174 min
React, TypeScript, and TDD
Top Content
Featured WorkshopFree
ReactJS is wildly popular and thus wildly supported. TypeScript is increasingly popular, and thus increasingly supported.

The two together? Not as much. Given that they both change quickly, it's hard to find accurate learning materials.

React+TypeScript, with JetBrains IDEs? That three-part combination is the topic of this series. We'll show a little about a lot. Meaning, the key steps to getting productive, in the IDE, for React projects using TypeScript. Along the way we'll show test-driven development and emphasize tips-and-tricks in the IDE.
GraphQL Galaxy 2021GraphQL Galaxy 2021
140 min
Build with SvelteKit and GraphQL
Top Content
Featured WorkshopFree
Have you ever thought about building something that doesn't require a lot of boilerplate with a tiny bundle size? In this workshop, Scott Spence will go from hello world to covering routing and using endpoints in SvelteKit. You'll set up a backend GraphQL API then use GraphQL queries with SvelteKit to display the GraphQL API data. You'll build a fast secure project that uses SvelteKit's features, then deploy it as a fully static site. This course is for the Svelte curious who haven't had extensive experience with SvelteKit and want a deeper understanding of how to use it in practical applications.

Table of contents:
- Kick-off and Svelte introduction
- Initialise frontend project
- Tour of the SvelteKit skeleton project
- Configure backend project
- Query Data with GraphQL
- Fetching data to the frontend with GraphQL
- Styling
- Svelte directives
- Routing in SvelteKit
- Endpoints in SvelteKit
- Deploying to Netlify
- Navigation
- Mutations in GraphCMS
- Sending GraphQL Mutations via SvelteKit
- Q&A
React Advanced Conference 2022React Advanced Conference 2022
148 min
Best Practices and Advanced TypeScript Tips for React Developers
Top Content
Featured Workshop
Are you a React developer trying to get the most benefits from TypeScript? Then this is the workshop for you.In this interactive workshop, we will start at the basics and examine the pros and cons of different ways you can declare React components using TypeScript. After that we will move to more advanced concepts where we will go beyond the strict setting of TypeScript. You will learn when to use types like any, unknown and never. We will explore the use of type predicates, guards and exhaustive checking. You will learn about the built-in mapped types as well as how to create your own new type map utilities. And we will start programming in the TypeScript type system using conditional types and type inferring.
React Advanced Conference 2022React Advanced Conference 2022
95 min
End-To-End Type Safety with React, GraphQL & Prisma
Featured WorkshopFree
In this workshop, you will get a first-hand look at what end-to-end type safety is and why it is important. To accomplish this, you’ll be building a GraphQL API using modern, relevant tools which will be consumed by a React client.
Prerequisites: - Node.js installed on your machine (12.2.X / 14.X)- It is recommended (but not required) to use VS Code for the practical tasks- An IDE installed (VSCode recommended)- (Good to have)*A basic understanding of Node.js, React, and TypeScript
GraphQL Galaxy 2022GraphQL Galaxy 2022
112 min
GraphQL for React Developers
Featured Workshop
There are many advantages to using GraphQL as a datasource for frontend development, compared to REST APIs. We developers in example need to write a lot of imperative code to retrieve data to display in our applications and handle state. With GraphQL you cannot only decrease the amount of code needed around data fetching and state-management you'll also get increased flexibility, better performance and most of all an improved developer experience. In this workshop you'll learn how GraphQL can improve your work as a frontend developer and how to handle GraphQL in your frontend React application.
React Summit 2022React Summit 2022
173 min
Build a Headless WordPress App with Next.js and WPGraphQL
Top Content
WorkshopFree
In this workshop, you’ll learn how to build a Next.js app that uses Apollo Client to fetch data from a headless WordPress backend and use it to render the pages of your app. You’ll learn when you should consider a headless WordPress architecture, how to turn a WordPress backend into a GraphQL server, how to compose queries using the GraphiQL IDE, how to colocate GraphQL fragments with your components, and more.