Skip to content

params argument in generatePath utility has incorrect type #14006

@anonpay-sh

Description

@anonpay-sh

Reproduction

https://stackblitz.com/edit/github-fguzcsck?file=app%2Froutes%2Fhome.tsx

Note that you may need to click in the editor and add then remove a space to trigger a type-checking pass.

System Info

System:
  OS: Linux 5.0 undefined
  CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
  Memory: 0 Bytes / 0 Bytes
  Shell: 1.0 - /bin/jsh
Binaries:
  Node: 20.19.1 - /usr/local/bin/node
  Yarn: 1.22.19 - /usr/local/bin/yarn
  npm: 10.8.2 - /usr/local/bin/npm
  pnpm: 8.15.6 - /usr/local/bin/pnpm
npmPackages:
  @react-router/dev: ^7.5.3 => 7.6.3
  @react-router/node: ^7.5.3 => 7.6.3
  @react-router/serve: ^7.5.3 => 7.6.3
  react-router: ^7.5.3 => 7.6.3
  vite: ^6.3.3 => 6.3.5

Used Package Manager

npm

Expected Behavior

As shown as the reproduction, the current runtime behavior of generatePath is as follows:

  • generatePath("/users/:id?", { id: "123" }) returns /users/123.
  • generatePath("/users/:id?", { id: null }) returns /users.
  • generatePath("/users/:id?", { id: undefined }) returns /users.
  • generatePath("/users/:id?", {}) returns /users.

Because generatePath uses == null and != null checks in its implementation, it accepts either null or undefined for optional parameters.

const stringify = (p: any) =>
p == null ? "" : typeof p === "string" ? p : String(p);

invariant(optional === "?" || param != null, `Missing ":${key}" param`);

I would expect that its type signature would similarly accommodate all these options.

Actual Behavior

The params argument in generatePath currently has the type params: { [key in PathParam<Path>]: string | null; }, meaning it requires missing parameters to be specified as null, and doesn't allow them to be specified as undefined or omitted entirely.

params: {
[key in PathParam<Path>]: string | null;
} = {} as any

This is problematic because it rules out some of the usages that yield valid runtime behavior.

The expression generatePath("/users/:id?", { id: undefined }) currently gives the following type error:

Image

The expression generatePath("/users/:id?", {}) currently gives the following type error:

Image

To match the runtime behavior of generatePath, we should instead be using the type params: { [key in PathParam<Path>]?: string | null | undefined; }. The ? would allow a parameter to be omitted, and the | undefined would allow it to be undefined.

Note that once this change is made, the default value for params could also be simplified from = {} as any to just = {}, since {} would now be a valid value for the specified type.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions