Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typescript bug when used in conjunction with "fastify-type-provider-zod". #220

Open
2 tasks done
geovla93 opened this issue Jan 31, 2024 · 5 comments
Open
2 tasks done

Comments

@geovla93
Copy link

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Fastify version

4.25.2

Plugin version

4.4.0

Node.js version

20.9.0

Operating system

macOS

Operating system version (i.e. 20.04, 11.3, 10)

14.2.1

Description

I came across a weird bug today when I was building my API. Basically when using @fastify/auth plugin along with fastify-type-provider-zod package typescript complains. I get the following error:

Type 'preHandlerHookHandler<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, RouteGenericInterface, unknown, FastifySchema, FastifyTypeProviderDefault, FastifyBaseLogger>' is not assignable to type 'onRequestHookHandler<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, RouteGenericInterface, unknown, FastifySchema, ZodTypeProvider, FastifyBaseLogger> | onRequestHookHandler<...>[] | undefined'.
  Type 'preHandlerHookHandler<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, RouteGenericInterface, unknown, FastifySchema, FastifyTypeProviderDefault, FastifyBaseLogger>' is not assignable to type 'onRequestHookHandler<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, RouteGenericInterface, unknown, FastifySchema, ZodTypeProvider, FastifyBaseLogger>'.
    The 'this' types of each signature are incompatible.
      Type 'FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, ZodTypeProvider>' is not assignable to type 'FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProviderDefault>'.
        The types returned by 'after()' are incompatible between these types.
          Type 'FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, ZodTypeProvider> & PromiseLike<...>' is not assignable to type 'FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProviderDefault> & PromiseLike<...>'.
            Type 'FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, ZodTypeProvider> & PromiseLike<...>' is not assignable to type 'FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProviderDefault>'.
              The types of 'addSchema(...).addHook' are incompatible between these types.
                Type '{ <RouteGeneric extends import("/Users/geovla/Developer/Projects/apps/taskmaster/api/node_modules/.pnpm/[email protected]/node_modules/fastify/types/route").RouteGenericInterface = import("/Users/geovla/Developer/Projects/apps/taskmaster/api/node_modules/.pnpm/[email protected]/node_modules/fastify/types/route").RouteGene...' is not assignable to type '{ <RouteGeneric extends import("/Users/geovla/Developer/Projects/apps/taskmaster/api/node_modules/.pnpm/[email protected]/node_modules/fastify/types/route").RouteGenericInterface = import("/Users/geovla/Developer/Projects/apps/taskmaster/api/node_modules/.pnpm/[email protected]/node_modules/fastify/types/route").RouteGene...'. Two different types with this name exist, but they are unrelated.
                  Types of parameters 'hook' and 'hook' are incompatible.
                    Types of parameters 'opts' and 'opts' are incompatible.
                      Type 'RouteOptions<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, any, any, any, ZodTypeProvider, FastifyBaseLogger> & { ...; }' is not assignable to type 'RouteOptions<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, any, any, any, FastifyTypeProviderDefault, FastifyBaseLogger> & { ...; }'.
                        Type 'RouteOptions<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, any, any, any, ZodTypeProvider, FastifyBaseLogger> & { ...; }' is not assignable to type 'RouteOptions<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, any, any, any, FastifyTypeProviderDefault, FastifyBaseLogger>'.
                          Types of property 'handler' are incompatible.
                            Type 'RouteHandlerMethod<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, any, any, any, ZodTypeProvider, FastifyBaseLogger>' is not assignable to type 'RouteHandlerMethod<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, any, any, any, FastifyTypeProviderDefault, FastifyBaseLogger>'.
                              Type 'FastifyTypeProviderDefault' is not assignable to type 'ZodTypeProvider'.

The error is shown both in onRequest and preHandler hooks. I should mention that the error does not show up if I remove the app.auth() function and use the auth functions on their own or in an array.

Steps to Reproduce

Create a fastify server and install the mentioned packages along with zod. Create two auth functions and try to use them in either onRequest or preHandler hooks.

export default async function routes(app: FastifyInstance) {
  app
    .withTypeProvider<ZodTypeProvider>()
    .route({
      method: 'GET',
      url: '/',
      schema: {
        description: 'Get all users',
        tags: ['User'],
        response: {
          200: userResponseSchema.array(),
        },
      },
      onRequest: app.auth([app.authenticate, app.guard]),
      handler: getUsersHandler,
    });
}

Expected Behavior

I would like to use this package without this typescript error like this:

onRequest: app.auth([app.authenticate, app.guard])
@mcollina
Copy link
Member

mcollina commented Feb 1, 2024

I have no clue why this is happening unfortunately. A PR to fix would be awesome.

@geovla93
Copy link
Author

geovla93 commented Feb 1, 2024

Great I will fork the repo and play around with the type definitions. If I come up with a fix I will add a PR. Thanks for the feedback!

@geovla93
Copy link
Author

geovla93 commented Feb 1, 2024

Just want to update you on this. Apparently, this issue exists with other type providers as well as you can see in this issue on the fastify-type-provider-typebox package. It seems the problem is the return type of the fastify.auth([]) which is typed with the FastifyTypeProvider and not the specific type provider used in the project. Unfortunately, I'm not that proficient in typescript to fix this so for now I will use the suggestion in the issue to add as any wherever I use fastify.auth([]).

@vinayakakv
Copy link

vinayakakv commented Apr 6, 2024

I was poking around with index-test.d.ts and found a few things:

The passing case:

jsonSchemaToTS.route({
  method: 'GET',
  url: '/with-param',
  schema: {body: {type: 'object', properties: {param: {type: 'string'}}, required: ['param']}},
  preHandler: jsonSchemaToTS.auth([]),
  handler: (req) => {
    expectType<{ param: string, [x: string]: unknown }>(req.body)
  }
})

The failing case (req.body is of type unknown):

jsonSchemaToTS.get("/test", {
  preHandler: jsonSchemaToTS.auth([]),
  schema: { body: { type: 'object', properties: { param: { type: 'string' } }, required: ['param'] } },
}, (req) => {
    expectType<{ param: string, [x: string]: unknown }>(req.body)
})

As mentioned by @geovla93, the failing case starts to work if we do preHandler: jsonSchemaToTS.auth([]) as any

Update: just found that this also works

jsonSchemaToTS.get("/test", {
  preHandler: jsonSchemaToTS.auth([]),
  schema: { body: { type: 'object', properties: { param: { type: 'string' } }, required: ['param'] } },
  handler: (req) => {
    expectType<{ param: string, [x: string]: unknown }>(req.body)
  }
})

@bcomnes
Copy link

bcomnes commented Jun 18, 2024

I was experiencing a similar issue with fastify-type-provider-json-schema-to-ts where when the auth plugin was used in the preHandler, everything was resolving to unknown. I'm not quite sure what fixed it, but ensuring I was running 4.6.1 seemed to resolve the issue for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants