Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 844
Nate Smith Avatar asked Nov 10 '21 14:11

Nate Smith


People also ask

Does GraphQL work with TypeScript?

Using TypeScript and GraphQL ensures that static typing exists all through your application. Without TypeScript, you can still create query types with GraphQL.

What is Apollo TypeScript?

Apollo supports type definitions for TypeScript out of the box. Apollo Client ships with definitions in its associated npm package, so installation should be done for you after the libraries are included in your project. These docs assume you already have TypeScript configured in your project, if not start here.


Video Answer


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.

  • 1) the built in GraphQl Generator,
  • 2) A simpler roll your own with config webpack/loader
  • 3) using the GraphQl Fragments Ref., and then using the fragments you can componentize them like so GraphQl Fragments Sample

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

  • A. Look here https://www.graphql-code-generator.com/docs/plugins/typescript-graphql-files-modules for their ref. samples below.. you can setup something like this generator and then it will generate the code klisted in B

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,
    ...
  }
}
like image 52
Transformer Avatar answered Sep 25 '22 21:09

Transformer