How to configure `*.graphql` imports for TypeScript?

Viewed 2198

I want to publish a package that contains a type declaration for *.graphql "modules", and have projects consume the package so that they can write import statements for queries written in other files. Is this possible?

Here's what I have so far.

I have the following type, in a file named graphql.d.ts.

declare module '*.graphql' {
  import { DocumentNode } from 'graphql';
  const Schema: DocumentNode;

  export default defaultDocument;
}

And my package.json looks like this.

{
  "name": "@my-private-scope/type-graphql-imports",
  "version": "1.0.0",
  "types": "graphql.d.ts",
  "files": [
    "graphql.d.ts"
  ],
  "peerDependencies": {
    "graphql": ">=14.0.0"
  }
}

But after publishing this package and importing it into a different project, I have the following errors.

error TS2307: Cannot find module './query.graphql' or its corresponding type declarations.

Is there a way to configure the project so that these types are visible to the compiler?

1 Answers

If I understand you correctly, but there are two questions/answers, i.e. two things you are missing

  • A) on how to generate/modularize the graphql queries
  • & B) how to fix those for the typescript compiler errors your are having.

Lets begin, please consider the answers and their sub options...


Answer A:

Resuse/Modularize-- to generate/create the typescripts modules/components for your GraphQl Queries, you can use 3 options, i.e.

Option 1: there is a built in generator you can use to simplify things in combination with webpack.


generates: src/api/user-service/queries.d.ts
 documents: src/api/user-service/queries.graphql
 plugins:
   - typescript-graphql-files-modules
 config:
   # resulting module definition path glob: "*\/api/user-service/queries.graphql"
   modulePathPrefix: "/api/user-service/"
  • B, in a nutshell.. it allows you to have a query named MyQuery in my-query.graphql file, this template will generate the following code:

declare module '*/my-query.graphql' {
  import { DocumentNode } from 'graphql';
  const MyQuery: DocumentNode;

  export { MyQuery };

  export default defaultDocument;
}
Accordingly, you can import the generated types and use it in your code:

import myQuery from './my-query.graphql';

// OR

import { myQuery } from './my-query.graphql';

Option 2 Simpler e.g.


Simple form, I recommend using webpack loader to feed your webpack config apollo

loaders: [
  {
    test: /\.(graphql|gql)$/,
    exclude: /node_modules/,
    loader: 'graphql-tag/loader'
  }
]

Avoid double quotes and specicl characters in your queries.graphql

query GetAllRoles($value: String) {
 Role(filter: { role: $value }) {
    role
 }
}

Now, you can reuse it with query values

import GetAllRoles from './queries.graphql'
 .....
 this.apollo.query({
  query: GetAllRoles,
  variables: {
    value: GetAllRoles, 
  }
})
  .subscribe(....)

Some more examples and details for the module creation and resolvers here to help you


Answer B:

to fix the Typescript compiler errors your are facing

First, the typescript definitions/types for graphql are missing, and you have to manually configure/add/extend the Typescript definition.

// in your webpack.d.ts
declare module "*.gql" {
  const content: any;
  export default content;
}

declare module "*.graphql" {
  const content: any;
  export default content;
}

Second, if thats doesn't fix it, then also please try adding this in tsconfig.json, to prevent typescript compiler from applying module types to imported javascript.

// in your tsconfig.json
{
  "compilerOptions": {
    ...
  "allowJs": true,
  "checkJs": false,
    ...
  }
}
Related