{"id":16221604,"url":"https://github.com/medflyt/eslint-plugin-graphql-type-checker","last_synced_at":"2026-02-12T03:13:28.989Z","repository":{"id":42627489,"uuid":"394609003","full_name":"MedFlyt/eslint-plugin-graphql-type-checker","owner":"MedFlyt","description":"An ESLint plugin that generates \u0026 validates TypeScript type annotations for GraphQL queries.","archived":false,"fork":false,"pushed_at":"2024-06-06T14:00:22.000Z","size":1702,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-04-03T01:17:45.439Z","etag":null,"topics":["eslint","generated","gql","graphql","literal","plugin","template","types","typescript","typings","validation"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MedFlyt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-08-10T10:16:20.000Z","updated_at":"2024-06-06T14:00:25.000Z","dependencies_parsed_at":"2024-06-06T15:29:40.239Z","dependency_job_id":"053a14a9-91a5-4887-b3dc-f68b419d45df","html_url":"https://github.com/MedFlyt/eslint-plugin-graphql-type-checker","commit_stats":{"total_commits":64,"total_committers":4,"mean_commits":16.0,"dds":0.109375,"last_synced_commit":"947b965d5e1fcb1d5004c3d4c9702cf69a5eee26"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MedFlyt%2Feslint-plugin-graphql-type-checker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MedFlyt%2Feslint-plugin-graphql-type-checker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MedFlyt%2Feslint-plugin-graphql-type-checker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MedFlyt%2Feslint-plugin-graphql-type-checker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MedFlyt","download_url":"https://codeload.github.com/MedFlyt/eslint-plugin-graphql-type-checker/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246916763,"owners_count":20854514,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["eslint","generated","gql","graphql","literal","plugin","template","types","typescript","typings","validation"],"created_at":"2024-10-10T12:09:07.361Z","updated_at":"2026-02-12T03:13:28.796Z","avatar_url":"https://github.com/MedFlyt.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"## eslint-plugin-graphql-type-checker [![npm version](https://badge.fury.io/js/@medflyt%2Feslint-plugin-graphql-type-checker.svg)](https://www.npmjs.com/package/@medflyt/eslint-plugin-graphql-type-checker) [![Build Status](https://github.com/MedFlyt/eslint-plugin-graphql-type-checker/actions/workflows/build-test.yml/badge.svg?branch=master)](https://github.com/MedFlyt/eslint-plugin-graphql-type-checker/actions/workflows/build-test.yml?query=branch%3Amaster)\n\nThe [`eslint-plugin-graphql-type-checker`](https://www.npmjs.com/package/@medflyt/eslint-plugin-graphql-type-checker) package is an ESLint plugin that generates and validates TypeScript type annotations for GraphQL queries. It contains a single rule `@medflyt/graphql-type-checker/check-query-types`, which triggers on configured annotation targets (e.g. `useQuery`) and inspects queries passed as `gql` tagged templates (i.e. ``gql`query ..` ``). From the query and the schema associated with the anotation target, it infers an annotation for the result and argument types, which can be applied to the code as an ESLint fix.\n\n\u003cimg\n  alt=\"Plugin demo screencast\"\n  src=\"https://raw.githubusercontent.com/MedFlyt/eslint-plugin-graphql-type-checker/master/demo-screencast.gif\"\n  width=\"700\"\n/\u003e\n\n**NOTE:** The plugin is still a work in progress, and currently only supports query operations, without fragments, union types or interfaces.\n\n## Example\n\nAs an example, consider this basic schema:\n\n```graphql\ntype Query {\n  greeting(language: String!): Greeting!\n}\n\ntype Greeting {\n  greeting_id: ID!\n  message: String!\n}\n```\n\nWe can perform an untyped query with `useQuery` like this:\n\n```ts\nconst { data } = useQuery(\n  gql`\n    query GetGreeting($language: String!) {\n      greeting(language: $language) {\n        __typename\n        message\n      }\n    }\n  `,\n  {\n    variables: { language: 'english' }, // Strongly-typed variables\n  },\n)\n```\n\nIf the plugin is configured for `useQuery` with the appropriate schema, the code above will trigger this lint error:\n\n```text\nTarget should have a type annotation that matches the GraphQL query type\n```\n\nwith a suggestion to fix the code to\n\n```ts\nconst { data } = useQuery\u003c{ greeting: { __typename: 'Greeting'; message: string } }, { language: string }\u003e(\n  gql`\n    query GetGreeting($language: String!) {\n      greeting(language: $language) {\n        __typename\n        message\n      }\n    }\n  `,\n  {\n    variables: { language: 'english' },\n  },\n)\n```\n\nBoth `data` and `variables` are now strongly typed according to the query in the `gql` tagged template.\n\nIf the `useQuery` call already has a type annotation, the plugin will compare it to the inferred one (disregarding layout and redundant syntax, like extra parentheses), and propose a fix in case of a difference.\n\nTo minimize the need to reformat after applying a fix, the suggested code fixes are formatted with prettier, using the target project's prettier configuration, if it has one.\n\n# Installation\n\nInstall the plugin with\n\n```bash\nnpm install -D @medflyt/eslint-plugin-graphql-type-checker\n```\n\n# Configuration\n\nThe plugin only has a single rule `@medflyt/graphql-type-checker/check-query-types`, which has the following configuration (expressed as a TypeScript type):\n\n```ts\nexport type RuleOptions = [\n  {\n    annotationTargets: Array\u003c\n      (FunctionTarget | MethodTarget | TaggedTemplateTarget) \u0026 {\n        schemaFilePath: string\n      }\n    \u003e\n  },\n]\n\ntype FunctionTarget = { function: { name: string } }\ntype MethodTarget = { method: { objectName: string; methodName: string } }\ntype TaggedTemplateTarget = { taggedTemplate: { name: string } }\n```\n\nAn annotation target can be either a function name, an object/method name pair, or a tagged-template tag name, together with a schema file path.\n\n### Function target\n\nA function target will the trigger the plugin everywhere that function gets called. For example, to have the plugin target the `useQuery` call, use a configuration like this:\n\n```javascript\nmodule.exports = {\n  parser: \"@typescript-eslint/parser\",\n  plugins: [\"@typescript-eslint\", \"@medflyt/graphql-type-checker\"],\n  extends: [],\n  rules: {\n    \"@medflyt/graphql-type-checker/check-query-types\": [\n      \"error\", {\n        annotationTargets: [\n          {\n            function: { name: 'useQuery' },\n            schemaFilePath: 'src/schemas/some-schema.graphql',\n          },\n          // ... other annotation targets\n        ],\n      },\n    ],\n  // ... other rules\n  },\n};\n```\n\nThis will provide a type annotation to every `useQuery` call with a `gql` tagged template argument (i.e. ``useQuery(gql`..`)``), for example:\n\n```ts\nconst { data } = useQuery\u003c{ greeting: { message: string } }, { language: string }\u003e(\n  gql`\n    query GetGreeting($language: String!) {\n      greeting(language: $language) {\n        message\n      }\n    }\n  `,\n  { variables: { language: 'english' } },\n)\n```\n\nBoth `data` and `variables` here are strongly typed. See [`src/demo/queries/apollo/useQueryExample.tsx`](https://github.com/MedFlyt/eslint-plugin-graphql-type-checker/blob/master/src/demo/queries/apollo/useQueryExample.tsx) for the full source of this example.\n\nThe configuration above only works for `useQuery` calls that have a direct `gql` tagged-template argument. If the query is large, inlining it in the call clutters the code, and it makes more sense to declare it in a separate constant. To type queries declared separately, we can write a helper function to be be targeted by the plugin:\n\n```ts\nconst annotateQuery = \u003cTData, TVariables\u003e(gql: Apollo.DocumentNode): Apollo.TypedDocumentNode\u003cTData, TVariables\u003e =\u003e gql\n```\n\nIf the plugin configuration specifies a function target for `annotateQuery`, the plugin will provide annotations for queries wrapped in it, like this:\n\n```ts\nconst greetingQuery = annotateQuery\u003c{ greeting: { message: string } }, { language: string }\u003e(gql`\n  query GetGreeting($language: String!) {\n    greeting(language: $language) {\n      message\n    }\n  }\n`)\n```\n\nThe resulting `greetingQuery` will have type `Apollo.TypedDocumentNode\u003c{ greeting: { message: string } }, { language: string }\u003e` and can be used in a `useQuery` call to make it strongly typed:\n\n```ts\nconst { data } = useQuery(greetingQuery, { variables: { language: 'english' } })\n```\n\n(Full source: [`src/demo/queries/apollo/annotateQueryExample.tsx`](https://github.com/MedFlyt/eslint-plugin-graphql-type-checker/blob/master/src/demo/queries/apollo/annotateQueryExample.tsx)).\n\n### Object/method target\n\nAn object/method target only applies to direct method calls on objects (i.e. `OBJECT.METHOD`). This can be useful if a project has several schemas, since you can configure a separate object/method target for each schema:\n\n```ts\nannotationTargets: [\n  {\n    objectName: 'Schema1',\n    methodName: 'useQuery',\n    schemaFilePath: 'src/schemas/schema-1.graphql',\n  },\n  {\n    objectName: 'Schema2',\n    methodName: 'useQuery',\n    schemaFilePath: 'src/schemas/schema-2.graphql',\n  },\n  // ... other annotation targets\n]\n```\n\nIf you now use a named import `import * as Schema1 from '@apollo/client'`, all `Schema1.useQuery` calls in the module will trigger the plugin with the `src/schemas/schema-1.graphql` schema.\n\n### Tagged-template target\n\nIt is also possible to directly target tagged templates such as `gql`:\n\n```ts\nannotationTargets: [\n  {\n    taggedTemplate: { name: 'gql' },\n    schemaFilePath: 'src/schemas/some-schema.graphql',\n  },\n  // ... other annotation targets\n]\n```\n\nThis will annotate the `gql` call, so we need a generic version of it:\n\n```ts\nconst gql = function \u003cTData = Record\u003cstring, any\u003e, TVariables = Record\u003cstring, any\u003e\u003e(\n  literals: string | readonly string[],\n  ...args: any[]\n): Apollo.TypedDocumentNode\u003cTData, TVariables\u003e {\n  return Apollo.gql(literals, ...args)\n}\n```\n\nWe can now use this generic `gql` to write queries, and the plugin will provide type annotations (project wide, so all `gql` tagged templates will need to be the generic one):\n\n```ts\nconst greetingQuery = gql\u003c{ greeting: { message: string } }, { language: string }\u003e`#graphql\n  query GetGreeting($language: String!) {\n    greeting(language: $language) {\n      message\n    }\n  }\n`\n```\n\nNote that the VSCode GraphQL plugin currently does not recognize generic `gql` tagged templates as GraphQL, so an extra `#graphql` comment is necessary to enable syntax coloring and other GraphQL functionality.\n\nIt is also possible to target tagged templates with different tag names, for example to support different schemas, or to be able to still use the non-generic `gql`. The example in [`src/demo/queries/apollo/tgqlTaggedTemplateExample.tsx`](https://github.com/MedFlyt/eslint-plugin-graphql-type-checker/blob/master/src/demo/queries/apollo/tgqlTaggedTemplateExample.tsx) uses `tgql` to avoid annotating every instance of `gql` in the project.\n\nFor more examples, see the [`src/demo/.eslintrc.js`](https://github.com/MedFlyt/eslint-plugin-graphql-type-checker/blob/master/src/demo/.eslintrc.js) configuration, and the query samples in [`src/demo/queries`](https://github.com/MedFlyt/eslint-plugin-graphql-type-checker/blob/master/src/demo/queries).\n\n# Demo\n\nTo run the plugin directly from the sources, clone this repository, and run\n\n```bash\nnpm install\nnpm run install-demo\n```\n\nfollowed by either `npm run build` or `npm run build-watch`.\n\nThe plugin can now be called from the command line on the examples in `src/demo/queries`, for example with:\n\n```bash\nnpx eslint src/demo/queries/apollo/useQueryExample.tsx\n```\n\n(To see an error message, try changing `{ message: string }` to `{ message: number }` in the type annotation.)\n\nIf you have an ESLint editor extension, you can also open the samples in `src/demo/queries` in your editor and use the quick-fix suggestions to update the type annotations. Note that after changing the plugin sources and rebuilding, you will have to reload or restart the editor to see the effects.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmedflyt%2Feslint-plugin-graphql-type-checker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmedflyt%2Feslint-plugin-graphql-type-checker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmedflyt%2Feslint-plugin-graphql-type-checker/lists"}