Skip to content

Conversation

@scarf005
Copy link
Contributor

@scarf005 scarf005 commented Oct 21, 2025

fixes #5559

for some reason the type error isn't reproducible in TanStack/router repo. to check that the changes work:

  1. create an external repo (e.g vite tanstack router template)
  2. build packages with the changes
  3. locally install router packages

Summary by CodeRabbit

Release Notes

  • New Features
    • Routes now accept numeric values for path segments in addition to string values, improving flexibility when constructing navigation links throughout your application.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 21, 2025

Walkthrough

The TypeScript type signature for MakeRequiredPathParams in the Link component is updated to allow numeric values for path parameters, in addition to strings. This resolves a type mismatch where runtime code accepted numbers but the type system rejected them.

Changes

Cohort / File(s) Summary
Type Signature Update
packages/router-core/src/link.ts
Modified the params property type to conditionally map each parameter property K to Params[K] | number, allowing both string and numeric values for path parameters in the Link component.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~5–10 minutes

The change is a straightforward TypeScript type union update affecting a single file's public API. The modification is localized to one type signature with clear intent and minimal surface area, though it does touch a public interface and should be validated against the documented behavior.

Suggested reviewers

  • schiller-manuel
  • Sheraff

Poem

🐰 A rabbit's wisdom on types anew:
Numbers and strings, now both shine through!
Path params dance with numeric grace,
No more casting—they've found their place! ✨

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title "fix: type error when passing number to Link.params" directly and specifically describes the main change in the changeset. The modification to the MakeRequiredPathParams signature is precisely addressing the TypeScript type error that prevented numeric values from being passed to path parameters, which is exactly what the title conveys. The title is concise, clear, and provides sufficient context for a reviewer scanning the history to understand the primary change without ambiguity.
Linked Issues Check ✅ Passed The code changes directly address the requirements in linked issue #5559, which reports a TypeScript type error when passing numeric values to Link.params. The modification to the MakeRequiredPathParams signature now allows both string and numeric values by changing the params type to Params[K] | number, enabling the documented behavior of auto-stringifying numbers at runtime without a type error. The change is minimal, focused, and eliminates the workaround of manually wrapping numbers in String(), aligning perfectly with the expected behavior described in the issue.
Out of Scope Changes Check ✅ Passed All changes in this pull request are directly in scope with the linked issue #5559. Only the packages/router-core/src/link.ts file is modified, and specifically only the MakeRequiredPathParams signature is updated to address the reported TypeScript type error. No extraneous files, unrelated modifications, or scope creep are present—the change is narrowly focused on resolving the specific issue of allowing numeric values in path parameters without breaking the existing runtime behavior.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@nx-cloud
Copy link

nx-cloud bot commented Oct 21, 2025

🤖 Nx Cloud AI Fix Eligible

An automatically generated fix could have helped fix failing tasks for this run, but Self-healing CI is disabled for this workspace. Visit workspace settings to enable it and get automatic fixes in future runs.

To disable these notifications, a workspace admin can disable them in workspace settings.


View your CI Pipeline Execution ↗ for commit e530391

Command Status Duration Result
nx affected --targets=test:eslint,test:unit,tes... ❌ Failed 6m 5s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 1m 24s View ↗

☁️ Nx Cloud last updated this comment at 2025-10-21 02:15:04 UTC

@pkg-pr-new
Copy link

pkg-pr-new bot commented Oct 21, 2025

More templates

@tanstack/arktype-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/arktype-adapter@5560

@tanstack/directive-functions-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/directive-functions-plugin@5560

@tanstack/eslint-plugin-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/eslint-plugin-router@5560

@tanstack/history

npm i https://pkg.pr.new/TanStack/router/@tanstack/history@5560

@tanstack/nitro-v2-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/nitro-v2-vite-plugin@5560

@tanstack/react-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router@5560

@tanstack/react-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-devtools@5560

@tanstack/react-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-ssr-query@5560

@tanstack/react-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start@5560

@tanstack/react-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-client@5560

@tanstack/react-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-server@5560

@tanstack/router-cli

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-cli@5560

@tanstack/router-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-core@5560

@tanstack/router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools@5560

@tanstack/router-devtools-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools-core@5560

@tanstack/router-generator

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-generator@5560

@tanstack/router-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-plugin@5560

@tanstack/router-ssr-query-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-ssr-query-core@5560

@tanstack/router-utils

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-utils@5560

@tanstack/router-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-vite-plugin@5560

@tanstack/server-functions-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/server-functions-plugin@5560

@tanstack/solid-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router@5560

@tanstack/solid-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-devtools@5560

@tanstack/solid-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-ssr-query@5560

@tanstack/solid-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start@5560

@tanstack/solid-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-client@5560

@tanstack/solid-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-server@5560

@tanstack/start-client-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-client-core@5560

@tanstack/start-plugin-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-plugin-core@5560

@tanstack/start-server-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-core@5560

@tanstack/start-static-server-functions

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-static-server-functions@5560

@tanstack/start-storage-context

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-storage-context@5560

@tanstack/valibot-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/valibot-adapter@5560

@tanstack/virtual-file-routes

npm i https://pkg.pr.new/TanStack/router/@tanstack/virtual-file-routes@5560

@tanstack/zod-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/zod-adapter@5560

commit: e530391

@scarf005 scarf005 force-pushed the fix/5559/link-params-number-type-error branch from 997874b to a05b6f2 Compare October 21, 2025 02:06
for some reason the type error isn't reproducible in `TanStack/router` repo. to check that the changes work:
1. create an external repo (e.g vite tanstack router template)
2. build packages with the changes
3. locally install router packages
@scarf005 scarf005 force-pushed the fix/5559/link-params-number-type-error branch from a05b6f2 to e530391 Compare October 21, 2025 02:07
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 997874b and e530391.

📒 Files selected for processing (1)
  • packages/router-core/src/link.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript in strict mode with extensive type safety across the codebase

Files:

  • packages/router-core/src/link.ts
packages/router-core/**

📄 CodeRabbit inference engine (AGENTS.md)

Keep framework-agnostic core router logic in packages/router-core/

Files:

  • packages/router-core/src/link.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Test
  • GitHub Check: Preview
🔇 Additional comments (1)
packages/router-core/src/link.ts (1)

577-586: Verify the fix in an external project setup.

Since the issue is not reproducible within the TanStack/router repository but only in external projects, please verify that this change actually resolves the type error in a real-world setup.

As suggested in the PR description, please:

  1. Build the packages with these changes
  2. Create a minimal reproduction project (e.g., using Vite TanStack Router template)
  3. Install the locally built packages
  4. Verify that <Link to="/$foo/bar" params={{ foo: 3 }}> no longer produces a type error

This verification is critical since the issue manifests differently in external projects versus the monorepo.

Comment on lines +577 to +586
params: MakeRequiredParamsReducer<
TRouter,
'PATH',
TFrom,
TTo
> extends infer Params
? {
[K in keyof Params]: Params[K] | number
} & {}
: never
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Apply the same number allowance to optional path params.

The change allows numbers for required path params, but MakeOptionalPathParams (lines 547-553) doesn't have the same allowance. If numbers are auto-stringified at runtime per the documentation, this behavior should be consistent for both required and optional path parameters.

After fixing the type logic issue above, apply similar logic to MakeOptionalPathParams:

export interface MakeOptionalPathParams<
  in out TRouter extends AnyRouter,
  in out TFrom,
  in out TTo,
> {
  params?: true | (ParamsReducer<TRouter, 'PATH', TFrom, TTo> extends infer Params
    ? Params extends true
      ? true
      : Params extends (...args: any[]) => any
        ? Params
        : {
            [K in keyof Params]: Params[K] | number
          } & {}
    : never)
}
🤖 Prompt for AI Agents
In packages/router-core/src/link.ts around lines 547-553 and 577-586,
MakeOptionalPathParams currently doesn't allow numeric path param values while
MakeRequiredParamsReducer does; update MakeOptionalPathParams so its mapped type
also widens each param type to Params[K] | number (i.e., when resolving Params
into an object map, transform each key's type to allow number in addition to the
original type) and keep the existing true/functional branches intact so optional
params behave consistently with required params.

⚠️ Potential issue | 🟠 Major

Fix type logic to handle true and function cases.

The mapped type { [K in keyof Params]: Params[K] | number } assumes Params is an object with parameter keys, but MakeRequiredParamsReducer can also resolve to:

  • true (when params don't need to change between routes)
  • A function of type ParamsReducerFn

When Params is true, keyof true evaluates to never, causing the mapped type to become {} and lose the intended true semantic. When Params is a function, keyof Function includes properties like "length", "name", "call", etc., creating an incorrect type.

Consider this approach that explicitly handles all three cases:

-  params: MakeRequiredParamsReducer<
-    TRouter,
-    'PATH',
-    TFrom,
-    TTo
-  > extends infer Params
-    ? {
-        [K in keyof Params]: Params[K] | number
-      } & {}
-    : never
+  params: MakeRequiredParamsReducer<TRouter, 'PATH', TFrom, TTo> extends infer Params
+    ? Params extends true
+      ? true
+      : Params extends (...args: any[]) => any
+        ? Params
+        : {
+            [K in keyof Params]: Params[K] | number
+          } & {}
+    : never
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
params: MakeRequiredParamsReducer<
TRouter,
'PATH',
TFrom,
TTo
> extends infer Params
? {
[K in keyof Params]: Params[K] | number
} & {}
: never
params: MakeRequiredParamsReducer<TRouter, 'PATH', TFrom, TTo> extends infer Params
? Params extends true
? true
: Params extends (...args: any[]) => any
? Params
: {
[K in keyof Params]: Params[K] | number
} & {}
: never
🤖 Prompt for AI Agents
In packages/router-core/src/link.ts around lines 577 to 586, the current mapped
type assumes Params is an object and uses {[K in keyof Params]: Params[K] |
number} which breaks when MakeRequiredParamsReducer resolves to true (loses the
true semantic) or to a function (pulls in function keys); change the type to a
conditional that explicitly handles all three cases: if Params extends true then
keep true, else if Params extends the ParamsReducerFn type then keep Params (or
Params | number if numbers are valid for reducer functions per usage), else
treat Params as an object and map its keys to Params[K] | number; remove the
fallback to an empty intersection (& {}) and ensure the function case is
excluded from key remapping by using the conditional branches.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

type error when passing number to Link.params

1 participant