mercurius-js / mercurius

Implement GraphQL servers and gateways with Fastify
https://mercurius.dev/
MIT License
2.33k stars 234 forks source link

Types issue with Typescript module resolution node16 #1047

Closed iamchathu closed 7 months ago

iamchathu commented 9 months ago

I created a new typescript respository with following Typescript config.

{
  "$schema": "https://json.schemastore.org/tsconfig",
  "display": "Node 20",
  "_version": "20.1.0",
  "compilerOptions": {
    "lib": ["es2023"],
    "module": "node16",
    "target": "es2022",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "moduleResolution": "node16",
    "isolatedModules": true
  }
}

The following in the index.ts file as the example.

import fastify from 'fastify';
import mercurius, { IResolvers } from 'mercurius';

export const app = fastify({});

const schema = `
  type Query {
    add(x: Int, y: Int): Int
  }
`;

const resolvers: IResolvers = {
  Query: {
    add: async (_, { x, y }) => x + y,
  },
};

app.register(mercurius, {
  schema,
  resolvers,
});

app.get('/', async function (req, reply) {
  const query = '{ add(x: 2, y: 2) }';
  return reply.graphql(query);
});

app.listen({ port: 3000 });

The dependencies versions looks like following

"fastify": "^4.24.3",
"graphql": "^16.8.1",
"mercurius": "^13.2.2"
"typescript": "^5.2.2"

The error when transpiling the Typescript as the following,

src/index.ts:18:14 - error TS2769: No overload matches this call.
  Overload 1 of 3, '(plugin: FastifyPluginCallback<{ schema: string; resolvers: IResolvers<any, MercuriusContext>; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>, opts?: FastifyRegisterOptions<...> | undefined): FastifyInstance<...> & PromiseLike<...>', gave the following error.
    Argument of type 'typeof import("/Users/Chathu/Workspace/app-v3/node_modules/.pnpm/mercurius@13.2.2_graphql@16.8.1/node_modules/mercurius/index")' is not assignable to parameter of type 'FastifyPluginCallback<{ schema: string; resolvers: IResolvers<any, MercuriusContext>; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>'.
      Type 'typeof import("/Users/Chathu/Workspace/app-v3/node_modules/.pnpm/mercurius@13.2.2_graphql@16.8.1/node_modules/mercurius/index")' provides no match for the signature '(instance: FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProvider>, opts: { ...; }, done: (err?: Error | undefined) => void): void'.
  Overload 2 of 3, '(plugin: FastifyPluginAsync<{ schema: string; resolvers: IResolvers<any, MercuriusContext>; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>, opts?: FastifyRegisterOptions<...> | undefined): FastifyInstance<...> & PromiseLike<...>', gave the following error.
    Argument of type 'typeof import("/Users/Chathu/Workspace/app-v3/node_modules/.pnpm/mercurius@13.2.2_graphql@16.8.1/node_modules/mercurius/index")' is not assignable to parameter of type 'FastifyPluginAsync<{ schema: string; resolvers: IResolvers<any, MercuriusContext>; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>'.
      Type 'typeof import("/Users/Chathu/Workspace/app-v3/node_modules/.pnpm/mercurius@13.2.2_graphql@16.8.1/node_modules/mercurius/index")' provides no match for the signature '(instance: FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProvider>, opts: { ...; }): Promise<...>'.
  Overload 3 of 3, '(plugin: FastifyPluginCallback<{ schema: string; resolvers: IResolvers<any, MercuriusContext>; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger> | FastifyPluginAsync<...> | Promise<...> | Promise<...>, opts?: FastifyRegisterOptions<...> | undefined): FastifyInstance<...> & PromiseLike<...>', gave the following error.
    Argument of type 'typeof import("/Users/Chathu/Workspace/app-v3/node_modules/.pnpm/mercurius@13.2.2_graphql@16.8.1/node_modules/mercurius/index")' is not assignable to parameter of type 'FastifyPluginCallback<{ schema: string; resolvers: IResolvers<any, MercuriusContext>; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger> | FastifyPluginAsync<...> | Promise<...> | Promise<...>'.

18 app.register(mercurius, {
                ~~~~~~~~~

Found 1 error in src/index.ts:18

I used following tool the test the esm support and the the exports.

npx @arethetypeswrong/cli --from-npm mercurius@13.2.2               

mercurius v13.2.2

Build tools:
- typescript@^5.0.2

❗️ The resolved types use export default where the JavaScript file appears to use module.exports =. This will cause TypeScript under the node16 module mode to think an extra .default property access is required, but that will likely fail at runtime. These types should use export = instead of export default. https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseExportDefault.md

πŸ’€ Import failed to resolve to type declarations or JavaScript files. https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/NoResolution.md

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   β”‚ "mercurius"                  β”‚ "mercurius/examples/graphiql-plugin/plugin-sources" β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ node10            β”‚ ❗️ Incorrect default export β”‚ πŸ’€ Resolution failed                                β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ node16 (from CJS) β”‚ ❗️ Incorrect default export β”‚ πŸ’€ Resolution failed                                β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ node16 (from ESM) β”‚ ❗️ Incorrect default export β”‚ πŸ’€ Resolution failed                                β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ bundler           β”‚ ❗️ Incorrect default export β”‚ πŸ’€ Resolution failed                                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
jonnydgreen commented 9 months ago

Hey @iamchathu ! I was unable to replicate the issue using the instructions you provided, are you able to provide a link to a GH repo or your full package.json+package-lock.json for closer inspection? :)

iamchathu commented 9 months ago

@jonnydgreen Please refer here. https://github.com/iamchathu/mercurius-ts-example

Only thing seems I have not mentioned is setting up the type to module in the packages.json

jonnydgreen commented 8 months ago

Only thing seems I have not mentioned is setting up the type to module in the packages.json

Ah yep, that triggered the issue!

I believe I've figured it out: the mercurius index.d.ts is not nodenext compatible, so this will require a fix that would include a small refactor of the index.d.ts file. For example, the following changes to index.d.ts would resolve the issue:

type Mercurius = FastifyPluginCallback<mercurius.MercuriusOptions>

declare namespace mercurius {
  // ...

  export const mercurius: Mercurius
  export { mercurius as default }
}

declare module "fastify" {
  // ...
}

declare function mercurius(...params: Parameters<Mercurius>): ReturnType<Mercurius>
export = mercurius;

wdyt @mcollina ?

mcollina commented 8 months ago

That would be perfect. Can you send a PR?

jonnydgreen commented 8 months ago

Yep, absolutely! I'll get that done this week :)