11

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?

2
  • 2
    Could you please include your consumer project's tsconfig file/s as well any triple slash directives used in the consumer project? The first thing that came to mind is that you might not be including the library types (or including correctly) in your tsconfig but the issue might be quite deeper. A minimal reproducible example would be nice, since many factors can cause this behavior. Commented Nov 16, 2021 at 9:16
  • 1
    I was always amazed how people are opening bounties on questions and then just not showing up for the follow-ups. This happens surprisingly often! Commented Nov 22, 2021 at 16:41

1 Answer 1

8
+250

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,
    ...
  }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.