graphql-typed-document-node
This repository is the home for graphql-typed-document-node
and integration related to it.
You can read more, see example and try it out live here
graphql-typed-document-node
is a development tool for creating fully typed DocumentNode
objects. It means that just by passing the GraphQL query/mutation/subscription/fragment to a supporting GraphQL client library, you'll get a fully type result object and variables object.
It made possible by TypeScript type inference.
This project works in the following way:
- Configure your project to use this library (see
How to use?
below). - Write your GraphQL operations (
query
/mutation
/subscription
/fragment
). - GraphQL Code Generator will generate a
TypedDocumentNode
for your operations (which is a bundle of pre-compiledDocumentNode
with the operation result type and variables type). - You'll get automatic type inference, auto-complete and type checking based on your GraphQL operation.
Supported Libraries
As of 2022, most GraphQL Client libraries supports TypedDocumentNode
out of the box.
The following patches are currently supported:
Built-in support
@apollo/client
(v4 and also,>=3.2.0
, if you are using React Components (<Query>
) you still need a patch)apollo-angular
(since2.6.0
)@urql/core
(since1.15.0
)@urql/preact
(since1.4.0
)urql
(since1.11.0
)@urql/exchange-graphcache
(since3.1.11
)@urql/svelte
(since1.1.3
)villus
(since1.0.0-beta.8
)graphql-js
(since15.2.0
)@vue/apollo-composable
(since4.0.0-alpha.13
)graphql-request
(since5.0.0
)graphql-js
(since v16)
How to use?
‼️ In most cases, you should not deal withTypedDocumentNode
directly, but use a library that supports it under the hood.
We recommend to use GraphQL Codegen with client-preset
for the ideal setup. You can follow the guides section in GraphQL-Codegen website
Utils
The core
package of typed-document-node exports 3 types only:
TypedDocumentNode
- the base of this library.ResultOf
- a utils for extracting the result type from an existingTypeDocumentNode
instance (ResultOf<typeof MyQueryDocument>
)VariablesOf
- a utils for extracting the variables type from an existingTypeDocumentNode
instance (VariablesOf<typeof MyQueryDocument>
)
How can I support this in my library?
If you are a library maintainer, and you wish to have built-in TS support in your library, you can add support for TypedDocumentNode
without having any breaking changes to your API.
Basically, in any place where you need to have typed access to the result type of an operation, or to a typed variables object, make sure to have generics for both types, and use TypeDocumentNode
in your arguments, instead of DocumentNode
. This will allow TypeScript to infer the types based on the object you are passing to it later.
Before
type GqlFetchResult = {
data?: any;
errors?: Error[];
};
export function gqlFetch(
operation: DocumentNode,
variables?: Record<string, any>
): GqlFetchResult {
// ...
}
After
import { TypedDocumentNode } from "@graphql-typed-document-node/core";
type GqlFetchResult<TData = any> = {
data?: TData;
errors?: Error[];
};
export function gqlFetch<TData = any, TVariables = Record<string, any>>(
operation: TypedDocumentNode<TData, TVariables>,
variables?: TVariables
): GqlFetchResult<TData>;
export function gqlFetch<TData = any, TVariables = Record<string, any>>(
operation: DocumentNode,
variables?: TVariables
): GqlFetchResult<TData> {
// ...
}
Thanks & Inspiration
- dotansimha/graphql-code-generator#1777 (comment) for the concept of generating unified clients support
- https://github.com/Shopify/quilt/blob/main/packages/graphql-typed/src/index.ts for similar idea