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

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions