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

Unable to use a Typescript generic for the Params property off of the request #207

Closed
2 tasks done
hershmire opened this issue Oct 27, 2023 · 5 comments · Fixed by #211
Closed
2 tasks done

Unable to use a Typescript generic for the Params property off of the request #207

hershmire opened this issue Oct 27, 2023 · 5 comments · Fixed by #211
Labels
bug Confirmed bug help wanted Help the community by contributing to this issue

Comments

@hershmire
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.13.0

Plugin version

4.3.0

Node.js version

18.17.1

Operating system

macOS

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

14.0

Description

I'm trying to use a generic on the Params property for a function that's sent to @fastify/auth. However, when I do this, I get the following Typescript error:

Type '(request: FastifyRequest<{    Params: Partial<GetUserRequestParams>;}>, reply: FastifyReply) => Promise<void>' is not assignable to type 'FastifyAuthFunction | FastifyAuthFunction[]'.
  Type '(request: FastifyRequest<{    Params: Partial<GetUserRequestParams>;}>, reply: FastifyReply) => Promise<void>' is not assignable to type 'FastifyAuthFunction'.
    Types of parameters 'request' and 'request' are incompatible.
      Type 'FastifyRequest<RouteGenericInterface, RawServerDefault, IncomingMessage, FastifySchema, FastifyTypeProviderDefault, unknown, FastifyBaseLogger, ResolveFastifyRequestType<...>>' is not assignable to type 'FastifyRequest<{ Params: Partial<{ userId: string; }>; }, RawServerDefault, IncomingMessage, FastifySchema, FastifyTypeProviderDefault, unknown, FastifyBaseLogger, ResolveFastifyRequestType<...>>'.
        Type 'RouteGenericInterface' is not assignable to type '{ Params: Partial<{ userId: string; }>; }'.
          Types of property 'Params' are incompatible.
            Type 'unknown' is not assignable to type 'Partial<{ userId: string; }>'.ts(2322)

I'm unsure if this is a bug or I'm doing this incorrectly.

Steps to Reproduce

Below is a snippet of what I'm doing:

import { 
  FastifyInstance,
  FastifyReply,
  FastifyRequest, 
} from 'fastify';
import { Static, Type } from '@sinclair/typebox';

const GetUserRequestParamsSchema = Type.Object({
  userId: Type.String(),
});

type GetUserRequestParams = Static<typeof GetUserRequestParamsSchema>;

const usersMutationAccessPolicy =
  (fastify: FastifyInstance) =>
  async (
    // Looking to extend Params so Typescript knows about `userId` (below)
    request: FastifyRequest<{
      Params: Partial<GetUserRequestParams>;
    }>,
    reply: FastifyReply,
  ): Promise<void> => {
    const { user } = request.identity;
    // Without extending request.params, it thinks the type is unknown
    const isOwner = user?.id === request.params.userId;

    // do more work below
  }

// Leaving out app startup code to keep this concise

export async function usersController(fastify: FastifyInstance): Promise<void> {
  fastify.patch<{
    Params: UserParams;
    Body: UserPatchBody;
  }>(
    `/:userId`,
    {
      schema: { ... },
      // Getting TS error 
      onRequest: fastify.auth([usersMutationAccessPolicy(fastify)]),
    },
    async (req, res) => {
      const user = await doPatchStuffWithUser();
      res.send(user);
    },
  );
}

Something to note. If I just added usersMutationAccessPolicy(fastify) to the onRequest directly, everything works as expected. Example:

export async function usersController(fastify: FastifyInstance): Promise<void> {
  fastify.patch<{
    Params: UserParams;
    Body: UserPatchBody;
  }>(
    `/:userId`,
    {
      schema: { ... },
      // Works as expected 
      onRequest: usersMutationAccessPolicy(fastify),
    },
    async (req, res) => {
      const user = await doPatchStuffWithUser();
      res.send(user);
    },
  );
}

However, I'm looking to use @fastify/auth to compose more access policy functions.

Expected Behavior

I don't receive any TS error when using

onRequest: fastify.auth([usersMutationAccessPolicy(fastify)]), from above.

@mcollina
Copy link
Member

Thanks for reporting!

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 file, create a new repository on GitHub and add a link to that.

@hershmire
Copy link
Author

@mcollina here's a repo that reproduces this issue https://github.com/hershmire/fastify-auth-ts-bug.

@hershmire
Copy link
Author

@mcollina any update on this?

@mcollina
Copy link
Member

As you could imagine, I have been swamped. As things are, I'm not sure I'd have time to get to this bugs anytime soon. However, I'd love to see a PR that fixes this.

@mcollina mcollina added bug Confirmed bug help wanted Help the community by contributing to this issue labels Dec 26, 2023
@Puppo
Copy link
Contributor

Puppo commented Jan 11, 2024

Hey @mcollina and @hershmire, I created this small PR #211 to fix this issue.
I hope it's ok; otherwise, let me know, and I'll fix it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Confirmed bug help wanted Help the community by contributing to this issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants