Skip to content

Conditionals in FastifyRequest based on ContextConfig broken since 4.19.0 #5322

@BrianValente

Description

@BrianValente

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.26.1

Plugin version

No response

Node.js version

18.17.1

Operating system

macOS

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

14.3.1

Description

Hello! In my project I have conditionals for the FastifyRequest type based on the route config in FastifyContextConfig. For example, I can add a needsUserCountry config to FastifyContextConfig like this:

declare module 'fastify' {
  interface FastifyRequest<ContextConfig extends FastifyContextConfig> {
    country: ContextConfig['needsUserCountry'] extends true ? string : never;
  }

  interface FastifyContextConfig {
    needsUserCountry?: boolean;
  }
}

And then create a route like this:

app.get(
  '/countryStringLength',
  {
    config: {
      needsUserCountry: true,
    },
  },
  async (req) => req.country.length,
);

The config will be handled by a hook, so the value will be set and the type is correct.

If I set needsUserCountry to false or I don't set it, it will throw an error due to req.country being never:
image

And if I set it to true, it will work.
image

In newer releases this behavior is broken.

In 4.19.0 and 4.19.1 the config type requires url and method, passing random values makes it work. The behavior of needsUserCountry works as expected.
image
image
image

Since 4.20 url and method are no longer required, but now configs are not being detected, as if I didn't pass a config object.
image

Steps to Reproduce

Try this code with Fastify 4.18 and 4.26.1. In 4.18 it will work, in 4.26.1 types will fail.

import fastify from 'fastify';

const app = fastify();

declare module 'fastify' {
  interface FastifyRequest<ContextConfig extends FastifyContextConfig> {
    country: ContextConfig['needsUserCountry'] extends true ? string : never;
  }

  interface FastifyContextConfig {
    needsUserCountry?: boolean;
  }
}

app.get(
  '/countryStringLength',
  {
    config: {
      needsUserCountry: true,
    },
  },
  async (req) => req.country.length,
);

Expected Behavior

I expect the req object passed to the handler to have the correct types based on the config object of the endpoint.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions