fastify / fastify-plugin

Plugin helper for Fastify
MIT License
198 stars 43 forks source link

Cannot pass in RawServer generic type #191

Closed olyop closed 2 years ago

olyop commented 2 years ago

Prerequisites

Fastify version

4.3.0

Plugin version

4.1.0

Node.js version

18.7.0

Operating system

Linux

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

Fedora Workstation 36

Description

The default export fp only allows a Options generic. This means you cannot pass in a function of type FastifyPluginAsync<MyOptions, MyRawServer, MyTypeProvider> for instance. I believe you should be able to pass in the two other generics as it has some use cases, in my case creating a package that can accept any RawServer type.

This results in a ts error like this:

Argument of type 'FastifyPluginAsync<Options, RawServer, FastifyTypeProviderDefault>' is not assignable to parameter of type 'FastifyPluginCallback<Options, Server, FastifyTypeProviderDefault>'.
  Types of parameters 'instance' and 'instance' are incompatible.
    ...

This is the types I believe would fix this, happy to make a pull request.

export default function fp<
  Options extends FastifyPluginOptions = Record<never, never>,
  Server extends RawServerBase = RawServerDefault,
  TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault,
>(
  fn: FastifyPluginAsync<Options, Server, TypeProvider>,
  ...
): FastifyPluginAsync<Options, Server, TypeProvider>

Steps to Reproduce

Pass in a function of type FastifyPluginAsync<MyOptions, MyRawServer, MyTypeProvider> to the fp function.

Expected Behavior

You should be able to pass in the generics manually or be inferred.

mcollina commented 2 years ago

cc @fastify/typescript

RafaelGSS commented 2 years ago

Could you create a reproducible code? Reference: https://stackoverflow.com/help/minimal-reproducible-example.

I believe the MyOptions needs to extend FastifyPluginOptions to make it work

olyop commented 2 years ago

You shouldn't have to pass in FastifyPluginOptions as the generic already extends it in this package.

Reproducible code:

interface MyOptions extends FastifyPluginOptions {
    foo: "bar",
}

const myPlugin: FastifyPluginAsync<MyOptions, Http2SecureServer> =
    async fastify => {
        fastify.get("/", request => {
            console.log(request.method)
            return "baz"
        })
    }

export const passInMyPlugin =
    fp(myPlugin) // Error
No overload matches this call.
  The last overload gave the following error.
    Argument of type 'FastifyPluginAsync<MyOptions, Http2SecureServer, FastifyTypeProviderDefault>' is not assignable to parameter of type 'FastifyPluginCallback<MyOptions, Server, FastifyTypeProviderDefault>'.
      Types of parameters 'instance' and 'instance' are incompatible.
        Type 'FastifyInstance<Server, IncomingMessage, ServerResponse, FastifyLoggerInstance, FastifyTypeProviderDefault>' is not assignable to type 'FastifyInstance<Http2SecureServer, Http2ServerRequest, Http2ServerResponse, FastifyLoggerInstance, FastifyTypeProviderDefault>'.
          Types of property 'server' are incompatible.
            Type 'Server' is not assignable to type 'Http2SecureServer'.ts(2769)
plugin.d.ts(19, 25): The last overload is declared here.

This is just a simple TypeScript bug and can easily be solved by passing in the RawServer type as shown in my previous comment. Just like all the exports in fastify they have these generics passed in everywhere.

Happy to make a pull request.

Uzlopak commented 2 years ago

Installing @type/node also removes some of those issues.

olyop commented 2 years ago

Hello, I have the latest @types/node package installed.

mcollina commented 2 years ago

Can you provide steps to reproduce? We often need a reproducible example, e.g. some code that allows someone else to recreate your problem by just copying and pasting it. If it involves more than a couple of different files, create a new repository on GitHub and add a link to that.

olyop commented 2 years ago

Yep sure. I have the repo for the package that I'm working on that has this error.

This links to the line number were the error occurs: https://github.com/olyop/apollo-server-fastify/blob/main/src/plugin.ts#L32

As you can see I have a problem with overloads we're I need to define the return type of the function and I need to pass in a RawServer type but cannot in the implementation function.

olyop commented 2 years ago

@mcollina I have created a pull request. Please let me know if you think this should be fixed or not.