3.2.0 • Published 1 year ago

@graphql-typed-document-node/core v3.2.0

Weekly downloads
812,419
License
MIT
Repository
github
Last release
1 year ago

graphql-typed-document-node

This repository is the home for graphql-typed-document-node and integration related to it.

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 and by the fact that TypeScript allows to do module augmentation.

This project works in the following way:

  1. Configure your project to use this library, using TypeScript configuration (see Getting Started), based on the client framework you use.
  2. You write your GraphQL operations (query / mutation / subscription / fragment) in any way your prefer (for example - in a .graphql file).
  3. GraphQL Code Generator will generate a TypedDocumentNode for your operations (which is a bundle of pre-compiled DocumentNode with the operation result type and variables type).
  4. Instead of using your .graphql file - import the generated TypedDocumentNode and use it with your GraphQL client framework.
  5. You'll get automatic type inference, auto-complete and type checking based on your GraphQL operation.

Supported Libraries

Most libraries supports DocumentNode as the type of the query object, but that's not enough to use this library.

In order to extend the behaviour, we are using TypeScript declaration merging to extend libraries support for TypedDocumentNode and add the support for type inference. This packages are loaded the same as @types/ packages, and doesn't effect your runtime, it just extends type declarations for the client library you use.

PackageSupporting PackageDetails
apollo-client (v2)@graphql-typed-document-node/apollo-client-2Core library
@apollo/client (v3)@graphql-typed-document-node/apollo-client-3Core library and React hooks
react-apollo (v3)@graphql-typed-document-node/react-apolloReact Hooks
graphql@graphql-typed-document-node/graphqlexecute and executeSync
urqlNot supported yetRequires: 1
graphql-requestNot supported yetRequires: 1, 2

How to use?

You can find a set of examples here

To use this library, following these instructions:

  1. Install GraphQL Codegen and the relevant plugins by doing:
yarn add -D @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/typescript-operations @graphql-codegen/typed-document-node

And if you don't already have a dependency for graphql, add it to your project:

Codegen is needed because we need to precompile .graphql files into DocumentNode, and burns the types in it to create TypedDocumentNode object.

  1. Create GraphQL-Codegen configuration file, and point to your GraphQL schema and your .graphql operations files:
schema: SCHEMA_FILE_OR_ENDPOINT_HERE
documents: "./src/**/*.graphql"
generates:
  ./src/graphql-operations.ts:
    plugins:
      - typescript
      - typescript-operations
      - typed-document-node
  1. Try to run codegen by using: yarn graphql-codegen, it should create the ./src/graphql-operations.ts file for you, with the generated TypedDocumentNode objects.

  2. Install the supporting library according to the GraphQL client you are using (see Supported Libraries section for the complete list), for example:

yarn add -D @graphql-typed-document-node/graphql

At this point, you can chose between adding support for TypedDocumentNode for your entire project by loading as part of your types configuration in tsconfig.json (change to the correct supporting library):

{
  "compilerOptions": {
    // ...
    "types": ["@graphql-typed-document-node/graphql"] 
    // ...
  }
}

Or, for only a specific file using TypeScript's Triple-Slash Directives, by adding this to your file (change to the correct supporting library):

/// <reference types="@graphql-typed-document-node/graphql" />

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.

You can either use TypeScript's method overloading or extend the existing behaviour declaration of your methods.

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> {
  // ...
}

How to extend other libraries with this?

Take a look at our support types libraries under ./packages/support/. You can easily extend other libraries to support TypedDocumentNode, even without changing the library code.

@graphql-tools/utilsgraphql-request@apollo/clientexample-app-hapiexample-app-httpexample-app-koaexample-app-nextjs@artanaliji/apollo-clientuse-graphql-ts@infinitebrahmanuniverse/nolb-_graph@everything-registry/sub-chunk-374fusegithub-events-email-templategraphql-modulesgraphql-request-msgpackgraphql-client-hybridgraphql-jitgraphql-hooksexample-complete-hapiexample-complete-httpexample-complete-koaexample-complete-nextjsdrupal-graphql-clienthashnode-gqlmirpayloadklabban-commerceklabban-commerce-kitklabban-commerce2msand-apollo-cache-hermesmsand-apollo-clientmercurius-codegenmercurius-integration-testingnextjs-graphql-tailwind-boilerplaterivet-graphqlsolana-cartesi-web3-adaptershopify-bulk-exportstorybook-msw-addontaro-apollo-clientweapp-graphql-requesttyped-graphql-builderxstate-viz-ycaptain@correttojs/eslint-config@custom.vendure/testing@daohaus/dao-data@daohaus/data-fetch-utils@daohaus/moloch-v3-data@daohaus/moloch-v3-legos@amapili/mercurius-codegen@ardatan/yoga@ambroos/graphql-codegen-preset-monorepo-client@andromedaprotocol/andromeda.js@awardit/graphql-ast-client@axah/postie-webapollo-client-npvn@crosscopy/corecanyon-ui@chromatic-protocol/graphql-request@comet/cms-admin@comet/admin-cms@collabland/component-lens@deedat5/keystone-core@deboxsoft/users-graphql-client@atellix/catalog@botstacks/chat-sdk@captemulation/graphql-modules@castle-xyz/apollo-client@bumjs/codegen-client-preset@graphql-ez/nextjs-testing@graphql-mesh/types@graphee/cli@graphql-codegen/client-preset@graphql-tools/executor@graphql-typed-document-node/apollo-client-2@graphql-typed-document-node/apollo-client-3@graphql-typed-document-node/graphql@graphql-typed-document-node/react-apollo@harshitp96/client@harshitp96/client-harshit@hattip/graphql@elevio/kb-kit@hoangvvo/graphql-jit@e965/8base-functions-types@gqlb/core@graqq/cli@graqq/core@digiv3rse/data-availability-verifier@half0wl/plain-typescript-sdk@graphcommerce/magento-graphcms@graphcommerce/magento-payment-mollie@financial-times/cp-content-pipeline-client@lorefnon/tql@isolve/apollo-client@fluencelabs/deal-ts-clients@macroos/auth-hooks@elasticpath/composable-common@igi-uk/types@faststore/core@fedexin40/auth-sdk@mem-labs/mem-node@linear/sdk