Repository: TanStack/router
Pull request #1696 (2024-06-02 21:00:35)

feat: merge unions for `search` and `params` for `Link` when `from` and `to` are loose
`Link`, `useNavigate` and `redirect` now merge unions for `search` and `params` under the following circumstances:
- When `from` is not used, previous `search` and `params` is a merged type
- When `from` and `to` is not used `search` and `params` is a merged type
- When `from` is not used and `to` is `.` or `..`
- Introduced a few optimizations for merging unions
- Introduced more correct optional/required behaviour for `params` and `search`

nx-cloud[bot]: # ☁️ Nx Cloud Report

CI is running for commit 6375c17b1568a4e56897808e44a732a531c94f4b.

[📂 Click to track the progress, see the status, the terminal output, and the build insights.](https://cloud.nx.app/cipes/665cdd8d95af1b2a73c54285?utm_source=pull-request&utm_medium=comment)


---

Sent with 💌 from [NxCloud.](https://nx.app?utm_source=pull-request&utm_medium=comment)

Patch:
diff --git a/packages/react-router/src/index.tsx b/packages/react-router/src/index.tsx
index 6e5e5c24d..47f151341 100644
--- a/packages/react-router/src/index.tsx
+++ b/packages/react-router/src/index.tsx
@@ -154,7 +154,6 @@ export {
   type ResolveFullSearchSchema,
   type ResolveFullSearchSchemaInput,
   type AnyRoute,
-  type ResolveAllParams,
   type RouteConstraints,
   type AnyRootRoute,
   type RootSearchSchema,
diff --git a/packages/react-router/src/link.tsx b/packages/react-router/src/link.tsx
index 77e96606c..2a63c5bcb 100644
--- a/packages/react-router/src/link.tsx
+++ b/packages/react-router/src/link.tsx
@@ -8,9 +8,10 @@ import type { AnyRouter, ParsedLocation } from '.'
 import type { HistoryState } from '@tanstack/history'
 import type { AnyRoute, RootSearchSchema } from './route'
 import type {
+  AllParams,
   CatchAllPaths,
-  ParseRoute,
-  ParseRouteWithoutBranches,
+  FullSearchSchema,
+  FullSearchSchemaInput,
   RouteByPath,
   RouteByToPath,
   RoutePaths,
@@ -257,15 +258,11 @@ export type ResolveRoute<
   TFrom,
   TTo,
   TPath = ResolveRelativePath<TFrom, TTo>,
-> = string extends TPath
-  ? ParseRouteWithoutBranches<TRouter['routeTree']>
-  : TPath extends CatchAllPaths
-    ? ParseRouteWithoutBranches<TRouter['routeTree']>
-    : TPath extends string
-      ? string extends TTo
-        ? RouteByPath<TRouter['routeTree'], TPath>
-        : RouteByToPath<TRouter, TPath>
-      : never
+> = TPath extends string
+  ? string extends TTo
+    ? RouteByPath<TRouter['routeTree'], TPath>
+    : RouteByToPath<TRouter, TPath>
+  : never
 
 type PostProcessParams<
   T,
@@ -275,17 +272,19 @@ type PostProcessParams<
 type ResolveFromParamType<TParamVariant extends ParamVariant> =
   TParamVariant extends 'PATH' ? 'allParams' : 'fullSearchSchema'
 
+type ResolveFromAllParams<
+  TRouter extends AnyRouter,
+  TParamVariant extends ParamVariant,
+> = TParamVariant extends 'PATH'
+  ? AllParams<TRouter['routeTree']>
+  : FullSearchSchema<TRouter['routeTree']>
+
 type ResolveFromParams<
   TRouter extends AnyRouter,
   TParamVariant extends ParamVariant,
   TFrom,
 > = string extends TFrom
-  ? PostProcessParams<
-      ParseRoute<
-        TRouter['routeTree']
-      >['types'][ResolveFromParamType<TParamVariant>],
-      TParamVariant
-    >
+  ? ResolveFromAllParams<TRouter, TParamVariant>
   : RouteByPath<
       TRouter['routeTree'],
       TFrom
@@ -294,16 +293,33 @@ type ResolveFromParams<
 type ResolveToParamType<TParamVariant extends ParamVariant> =
   TParamVariant extends 'PATH' ? 'allParams' : 'fullSearchSchemaInput'
 
+type ResolveAllToParams<
+  TRouter extends AnyRouter,
+  TParamVariant extends ParamVariant,
+> = TParamVariant extends 'PATH'
+  ? AllParams<TRouter['routeTree']>
+  : FullSearchSchemaInput<TRouter['routeTree']>
+
 export type ResolveToParams<
   TRouter extends AnyRouter,
   TParamVariant extends ParamVariant,
   TFrom,
   TTo,
-  TRoute extends AnyRoute = ResolveRoute<TRouter, TFrom, TTo>,
-> = PostProcessParams<
-  TRoute['types'][ResolveToParamType<TParamVariant>],
-  TParamVariant
->
+> =
+  ResolveRelativePath<TFrom, TTo> extends infer TPath
+    ? string extends TPath
+      ? ResolveAllToParams<TRouter, TParamVariant>
+      : TPath extends CatchAllPaths
+        ? ResolveAllToParams<TRouter, TParamVariant>
+        : PostProcessParams<
+            ResolveRoute<
+              TRouter,
+              TFrom,
+              TTo
+            >['types'][ResolveToParamType<TParamVariant>],
+            TParamVariant
+          >
+    : never
 
 type ResolveRelativeToParams<
   TRouter extends AnyRouter,
@@ -369,14 +385,8 @@ export interface MakeRequiredSearchParams<
   search: MakeRequiredParamsReducer<TRouter, 'SEARCH', TFrom, TTo> & {}
 }
 
-export type IsRequiredParams<TParams> = keyof TParams extends infer K extends
-  keyof TParams
-  ? K extends any
-    ? undefined extends TParams[K]
-      ? never
-      : true
-    : never
-  : never
+export type IsRequiredParams<TParams> =
+  Record<never, never> extends TParams ? never : true
 
 export type IsRequired<
   TRouter extends AnyRouter,
@@ -384,13 +394,15 @@ export type IsRequired<
   TFrom,
   TTo,
 > =
-  string extends ResolveRelativePath<TFrom, TTo>
-    ? never
-    : ResolveRelativePath<TFrom, TTo> extends CatchAllPaths
+  ResolveRelativePath<TFrom, TTo> extends infer TPath
+    ? string extends TPath
       ? never
-      : IsRequiredParams<
-          ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>
-        >
+      : TPath extends CatchAllPaths
+        ? never
+        : IsRequiredParams<
+            ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>
+          >
+    : never
 
 export type SearchParamOptions<
   TRouter extends AnyRouter,
diff --git a/packages/react-router/src/route.ts b/packages/react-router/src/route.ts
index f5e6ebc5d..e6170f533 100644
--- a/packages/react-router/src/route.ts
+++ b/packages/react-router/src/route.ts
@@ -16,14 +16,7 @@ import type { NavigateOptions, ParsePathParams, ToSubOptions } from './link'
 import type { ParsedLocation } from './location'
 import type { RouteById, RouteIds, RoutePaths } from './routeInfo'
 import type { AnyRouter, RegisteredRouter, Router } from './router'
-import type {
-  Assign,
-  Expand,
-  IsAny,
-  NoInfer,
-  PickRequired,
-  UnionToIntersection,
-} from './utils'
+import type { Assign, Expand, IsAny, NoInfer, PickRequired } from './utils'
 import type { BuildLocationFn, NavigateFn } from './RouterProvider'
 import type { NotFoundError } from './not-found'
 import type { LazyRoute } from './fileRoute'
@@ -52,8 +45,10 @@ export type RoutePathOptions<TCustomId, TPath> =
 
 export interface StaticDataRouteOption {}
 
-export type RoutePathOptionsIntersection<TCustomId, TPath> =
-  UnionToIntersection<RoutePathOptions<TCustomId, TPath>>
+export type RoutePathOptionsIntersection<TCustomId, TPath> = {
+  path: TPath
+  id: TCustomId
+}
 
 export type RouteOptions<
   TParentRoute extends AnyRoute = AnyRoute,
@@ -474,11 +469,6 @@ export type ResolveAllParamsFromParent<
   ? TParams
   : Assign<TParentRoute['types']['allParams'], TParams>
 
-export type ResolveAllParams<TParentRoute extends AnyRoute, TParams> =
-  Record<never, string> extends TParentRoute['types']['allParams']
-    ? TParams
-    : UnionToIntersection<TParentRoute['types']['allParams'] & TParams> & {}
-
 export type RouteConstraints = {
   TParentRoute: AnyRoute
   TPath: string
@@ -618,7 +608,7 @@ export class Route<
     TSearchSchema
   >,
   in out TParams = Record<ParsePathParams<TPath>, string>,
-  in out TAllParams = ResolveAllParams<TParentRoute, TParams>,
+  in out TAllParams = ResolveAllParamsFromParent<TParentRoute, TParams>,
   TRouteContextReturn = RouteContext,
   in out TRouteContext = ResolveRouteContext<TRouteContextReturn>,
   in out TAllContext = Assign<
@@ -960,7 +950,7 @@ export function createRoute<
   >,
   TFullSearchSchema = ResolveFullSearchSchema<TParentRoute, TSearchSchema>,
   TParams = Record<ParsePathParams<TPath>, string>,
-  TAllParams = ResolveAllParams<TParentRoute, TParams>,
+  TAllParams = ResolveAllParamsFromParent<TParentRoute, TParams>,
   TRouteContextReturn = RouteContext,
   TRouteContext = ResolveRouteContext<TRouteContextReturn>,
   TAllContext = Assign<
diff --git a/packages/react-router/src/routeInfo.ts b/packages/react-router/src/routeInfo.ts
index 3b33d097a..f9d5f51b7 100644
--- a/packages/react-router/src/routeInfo.ts
+++ b/packages/react-router/src/routeInfo.ts
@@ -114,20 +114,25 @@ export type RouteByToPath<TRouter extends AnyRouter, TTo> = Extract<
   AnyRoute
 >
 
-export type FullSearchSchema<TRouteTree extends AnyRoute> = Expand<
-  MergeUnion<
-    Exclude<ParseRoute<TRouteTree>['types']['searchSchema'], RootSearchSchema>
+export type FullSearchSchema<TRouteTree extends AnyRoute> = MergeUnion<
+  Exclude<ParseRoute<TRouteTree>['types']['fullSearchSchema'], RootSearchSchema>
+>
+
+export type FullSearchSchemaInput<TRouteTree extends AnyRoute> = MergeUnion<
+  Exclude<
+    ParseRoute<TRouteTree>['types']['fullSearchSchemaInput'],
+    RootSearchSchema
   >
 >
 
-export type AllParams<TRouteTree extends AnyRoute> = Expand<
-  MergeUnion<ParseRoute<TRouteTree>['types']['params']>
+export type AllParams<TRouteTree extends AnyRoute> = MergeUnion<
+  ParseRoute<TRouteTree>['types']['allParams']
 >
 
-export type AllContext<TRouteTree extends AnyRoute> = Expand<
-  MergeUnion<ParseRoute<TRouteTree>['types']['allContext']>
+export type AllContext<TRouteTree extends AnyRoute> = MergeUnion<
+  ParseRoute<TRouteTree>['types']['allContext']
 >
 
-export type AllLoaderData<TRouteTree extends AnyRoute> = Expand<
-  MergeUnion<ParseRoute<TRouteTree>['types']['loaderData']>
+export type AllLoaderData<TRouteTree extends AnyRoute> = MergeUnion<
+  ParseRoute<TRouteTree>['types']['loaderData']
 >
diff --git a/packages/react-router/src/utils.ts b/packages/react-router/src/utils.ts
index 95ef366f4..2601b73e4 100644
--- a/packages/react-router/src/utils.ts
+++ b/packages/react-router/src/utils.ts
@@ -26,12 +26,6 @@ export type Expand<T> = T extends object
     : never
   : T
 
-export type UnionToIntersection<T> = (
-  T extends any ? (k: T) => void : never
-) extends (k: infer I) => any
-  ? I
-  : never
-
 export type DeepPartial<T> = T extends object
   ? {
       [P in keyof T]?: DeepPartial<T[P]>
@@ -100,7 +94,7 @@ export type MergeUnionPrimitives<TUnion> = TUnion extends MergeUnionPrimitive
 
 export type MergeUnion<TUnion> =
   | MergeUnionPrimitives<TUnion>
-  | MergeUnionObject<MergeUnionObjects<TUnion>>
+  | MergeUnionObject<TUnion>
 
 export function last<T>(arr: Array<T>) {
   return arr[arr.length - 1]


Test patch:
diff --git a/packages/react-router/tests/link.test-d.tsx b/packages/react-router/tests/link.test-d.tsx
index dc7b09490..98724329e 100644
--- a/packages/react-router/tests/link.test-d.tsx
+++ b/packages/react-router/tests/link.test-d.tsx
@@ -1027,50 +1027,35 @@ test('when navigating to a route with params', () => {
     postId: string
   }>()
 
-  defaultRouterLinkParams
-    .parameter(0)
-    .toEqualTypeOf<
-      | {}
-      | { invoiceId: string }
-      | { postId: string }
-      | { invoiceId: string; detailId: string }
-    >()
+  defaultRouterLinkParams.parameter(0).toEqualTypeOf<{
+    invoiceId?: string
+    postId?: string
+    detailId?: string
+  }>()
 
-  defaultRouterObjectsLinkParams
-    .parameter(0)
-    .toEqualTypeOf<
-      | {}
-      | { invoiceId: string }
-      | { postId: string }
-      | { invoiceId: string; detailId: string }
-    >()
+  defaultRouterObjectsLinkParams.parameter(0).toEqualTypeOf<{
+    invoiceId?: string
+    postId?: string
+    detailId?: string
+  }>()
 
-  routerAlwaysTrailingSlashesLinkParams
-    .parameter(0)
-    .toEqualTypeOf<
-      | {}
-      | { invoiceId: string }
-      | { postId: string }
-      | { invoiceId: string; detailId: string }
-    >()
+  routerAlwaysTrailingSlashesLinkParams.parameter(0).toEqualTypeOf<{
+    invoiceId?: string
+    postId?: string
+    detailId?: string
+  }>()
 
-  routerNeverTrailingSlashesLinkParams
-    .parameter(0)
-    .toEqualTypeOf<
-      | {}
-      | { invoiceId: string }
-      | { postId: string }
-      | { invoiceId: string; detailId: string }
-    >()
+  routerNeverTrailingSlashesLinkParams.parameter(0).toEqualTypeOf<{
+    invoiceId?: string
+    postId?: string
+    detailId?: string
+  }>()
 
-  routerPreserveTrailingSlashesLinkParams
-    .parameter(0)
-    .toEqualTypeOf<
-      | {}
-      | { invoiceId: string }
-      | { postId: string }
-      | { invoiceId: string; detailId: string }
-    >()
+  routerPreserveTrailingSlashesLinkParams.parameter(0).toEqualTypeOf<{
+    invoiceId?: string
+    postId?: string
+    detailId?: string
+  }>()
 })
 
 test('when navigating from a route with no params to a route with params', () => {
@@ -1650,43 +1635,43 @@ test('when navigating to a union of routes with params', () => {
 
   expectTypeOf(DefaultRouterLink)
     .parameter(0)
-    .not.toMatchTypeOf<{ params: unknown }>()
+    .toMatchTypeOf<{ params: unknown }>()
 
   expectTypeOf(DefaultRouterObjectsLink)
     .parameter(0)
-    .not.toMatchTypeOf<{ params: unknown }>()
+    .toMatchTypeOf<{ params: unknown }>()
 
   expectTypeOf(RouterAlwaysTrailingSlashesLink)
     .parameter(0)
-    .not.toMatchTypeOf<{ params: unknown }>()
+    .toMatchTypeOf<{ params: unknown }>()
 
   expectTypeOf(RouterNeverTrailingSlashesLink)
     .parameter(0)
-    .not.toMatchTypeOf<{ params: unknown }>()
+    .toMatchTypeOf<{ params: unknown }>()
 
   expectTypeOf(RouterPreserveTrailingSlashesLink)
     .parameter(0)
-    .not.toMatchTypeOf<{ params: unknown }>()
+    .toMatchTypeOf<{ params: unknown }>()
 
   defaultRouterLinkParams
     .exclude<Function | boolean>()
-    .toEqualTypeOf<{ invoiceId: string } | { postId: string } | undefined>()
+    .toEqualTypeOf<{ invoiceId: string } | { postId: string }>()
 
   defaultRouterObjectsLinkParams
     .exclude<Function | boolean>()
-    .toEqualTypeOf<{ invoiceId: string } | { postId: string } | undefined>()
+    .toEqualTypeOf<{ invoiceId: string } | { postId: string }>()
 
   routerAlwaysTrailingSlashesLinkParams
     .exclude<Function | boolean>()
-    .toEqualTypeOf<{ invoiceId: string } | { postId: string } | undefined>()
+    .toEqualTypeOf<{ invoiceId: string } | { postId: string }>()
 
   routerNeverTrailingSlashesLinkParams
     .exclude<Function | boolean>()
-    .toEqualTypeOf<{ invoiceId: string } | { postId: string } | undefined>()
+    .toEqualTypeOf<{ invoiceId: string } | { postId: string }>()
 
   routerPreserveTrailingSlashesLinkParams
     .exclude<Function | boolean>()
-    .toEqualTypeOf<{ invoiceId: string } | { postId: string } | undefined>()
+    .toEqualTypeOf<{ invoiceId: string } | { postId: string }>()
 
   defaultRouterLinkParams.returns.toEqualTypeOf<
     { invoiceId: string } | { postId: string }
@@ -1708,50 +1693,35 @@ test('when navigating to a union of routes with params', () => {
     { invoiceId: string } | { postId: string }
   >()
 
-  defaultRouterLinkParams
-    .parameter(0)
-    .toEqualTypeOf<
-      | {}
-      | { invoiceId: string }
-      | { postId: string }
-      | { invoiceId: string; detailId: string }
-    >()
+  defaultRouterLinkParams.parameter(0).toEqualTypeOf<{
+    invoiceId?: string
+    postId?: string
+    detailId?: string
+  }>()
 
-  defaultRouterObjectsLinkParams
-    .parameter(0)
-    .toEqualTypeOf<
-      | {}
-      | { invoiceId: string }
-      | { postId: string }
-      | { invoiceId: string; detailId: string }
-    >()
+  defaultRouterObjectsLinkParams.parameter(0).toEqualTypeOf<{
+    invoiceId?: string
+    postId?: string
+    detailId?: string
+  }>()
 
-  routerAlwaysTrailingSlashesLinkParams
-    .parameter(0)
-    .toEqualTypeOf<
-      | {}
-      | { invoiceId: string }
-      | { postId: string }
-      | { invoiceId: string; detailId: string }
-    >()
+  routerAlwaysTrailingSlashesLinkParams.parameter(0).toEqualTypeOf<{
+    invoiceId?: string
+    postId?: string
+    detailId?: string
+  }>()
 
-  routerNeverTrailingSlashesLinkParams
-    .parameter(0)
-    .toEqualTypeOf<
-      | {}
-      | { invoiceId: string }
-      | { postId: string }
-      | { invoiceId: string; detailId: string }
-    >()
+  routerNeverTrailingSlashesLinkParams.parameter(0).toEqualTypeOf<{
+    invoiceId?: string
+    postId?: string
+    detailId?: string
+  }>()
 
-  routerPreserveTrailingSlashesLinkParams
-    .parameter(0)
-    .toEqualTypeOf<
-      | {}
-      | { invoiceId: string }
-      | { postId: string }
-      | { invoiceId: string; detailId: string }
-    >()
+  routerPreserveTrailingSlashesLinkParams.parameter(0).toEqualTypeOf<{
+    invoiceId?: string
+    postId?: string
+    detailId?: string
+  }>()
 })
 
 test('when navigating to a union of routes including the root', () => {
@@ -1885,50 +1855,35 @@ test('when navigating to a union of routes including the root', () => {
     { invoiceId: string } | { postId: string } | {}
   >()
 
-  defaultRouterLinkParams
-    .parameter(0)
-    .toEqualTypeOf<
-      | {}
-      | { invoiceId: string }
-      | { postId: string }
-      | { invoiceId: string; detailId: string }
-    >()
+  defaultRouterLinkParams.parameter(0).toEqualTypeOf<{
+    invoiceId?: string
+    postId?: string
+    detailId?: string
+  }>()
 
-  defaultRouterObjectsLinkParams
-    .parameter(0)
-    .toEqualTypeOf<
-      | {}
-      | { invoiceId: string }
-      | { postId: string }
-      | { invoiceId: string; detailId: string }
-    >()
+  defaultRouterObjectsLinkParams.parameter(0).toEqualTypeOf<{
+    invoiceId?: string
+    postId?: string
+    detailId?: string
+  }>()
 
-  routerAlwaysTrailingSlashesLinkParams
-    .parameter(0)
-    .toEqualTypeOf<
-      | {}
-      | { invoiceId: string }
-      | { postId: string }
-      | { invoiceId: string; detailId: string }
-    >()
+  routerAlwaysTrailingSlashesLinkParams.parameter(0).toEqualTypeOf<{
+    invoiceId?: string
+    postId?: string
+    detailId?: string
+  }>()
 
-  routerNeverTrailingSlashesLinkParams
-    .parameter(0)
-    .toEqualTypeOf<
-      | {}
-      | { invoiceId: string }
-      | { postId: string }
-      | { invoiceId: string; detailId: string }
-    >()
+  routerNeverTrailingSlashesLinkParams.parameter(0).toEqualTypeOf<{
+    invoiceId?: string
+    postId?: string
+    detailId?: string
+  }>()
 
-  routerPreserveTrailingSlashesLinkParams
-    .parameter(0)
-    .toEqualTypeOf<
-      | {}
-      | { invoiceId: string }
-      | { postId: string }
-      | { invoiceId: string; detailId: string }
-    >()
+  routerPreserveTrailingSlashesLinkParams.parameter(0).toEqualTypeOf<{
+    invoiceId?: string
+    postId?: string
+    detailId?: string
+  }>()
 })
 
 test('when navigating from a route with search params to the same route', () => {
@@ -2118,25 +2073,21 @@ test('when navigating to a route with search params', () => {
     page: number
   }>()
 
-  defaultRouterLinkSearch
-    .parameter(0)
-    .toEqualTypeOf<{} | { page: number } | { page?: number }>()
+  defaultRouterLinkSearch.parameter(0).toEqualTypeOf<{ page?: number }>()
 
-  defaultRouterObjectsLinkSearch
-    .parameter(0)
-    .toEqualTypeOf<{} | { page: number } | { page?: number }>()
+  defaultRouterObjectsLinkSearch.parameter(0).toEqualTypeOf<{ page?: number }>()
 
   routerAlwaysTrailingSlashesLinkSearch
     .parameter(0)
-    .toEqualTypeOf<{} | { page: number } | { page?: number }>()
+    .toEqualTypeOf<{ page?: number }>()
 
   routerNeverTrailingSlashesLinkSearch
     .parameter(0)
-    .toEqualTypeOf<{} | { page: number } | { page?: number }>()
+    .toEqualTypeOf<{ page?: number }>()
 
   routerPreserveTrailingSlashesLinkSearch
     .parameter(0)
-    .toEqualTypeOf<{} | { page: number } | { page?: number }>()
+    .toEqualTypeOf<{ page?: number }>()
 })
 
 test('when navigating to a route with optional search params', () => {
@@ -2253,25 +2204,21 @@ test('when navigating to a route with optional search params', () => {
     page?: number
   }>()
 
-  defaultRouterLinkSearch
-    .parameter(0)
-    .toEqualTypeOf<{} | { page: number } | { page?: number }>()
+  defaultRouterLinkSearch.parameter(0).toEqualTypeOf<{ page?: number }>()
 
-  defaultRouterObjectsLinkSearch
-    .parameter(0)
-    .toEqualTypeOf<{} | { page: number } | { page?: number }>()
+  defaultRouterObjectsLinkSearch.parameter(0).toEqualTypeOf<{ page?: number }>()
 
   routerAlwaysTrailingSlashesLinkSearch
     .parameter(0)
-    .toEqualTypeOf<{} | { page: number } | { page?: number }>()
+    .toEqualTypeOf<{ page?: number }>()
 
   routerNeverTrailingSlashesLinkSearch
     .parameter(0)
-    .toEqualTypeOf<{} | { page: number } | { page?: number }>()
+    .toEqualTypeOf<{ page?: number }>()
 
   routerPreserveTrailingSlashesLinkSearch
     .parameter(0)
-    .toEqualTypeOf<{} | { page: number } | { page?: number }>()
+    .toEqualTypeOf<{ page?: number }>()
 })
 
 test('when navigating from a route with no search params to a route with search params', () => {
@@ -2526,25 +2473,21 @@ test('when navigating to a union of routes with search params', () => {
     { page: number } | {}
   >()
 
-  defaultRouterLinkSearch
-    .parameter(0)
-    .toEqualTypeOf<{} | { page: number } | { page?: number }>()
+  defaultRouterLinkSearch.parameter(0).toEqualTypeOf<{ page?: number }>()
 
-  defaultRouterObjectsLinkSearch
-    .parameter(0)
-    .toEqualTypeOf<{} | { page: number } | { page?: number }>()
+  defaultRouterObjectsLinkSearch.parameter(0).toEqualTypeOf<{ page?: number }>()
 
   routerAlwaysTrailingSlashesSearch
     .parameter(0)
-    .toEqualTypeOf<{} | { page: number } | { page?: number }>()
+    .toEqualTypeOf<{ page?: number }>()
 
   routerNeverTrailingSlashesSearch
     .parameter(0)
-    .toEqualTypeOf<{} | { page: number } | { page?: number }>()
+    .toEqualTypeOf<{ page?: number }>()
 
   routerPreserveTrailingSlashesSearch
     .parameter(0)
-    .toEqualTypeOf<{} | { page: number } | { page?: number }>()
+    .toEqualTypeOf<{ page?: number }>()
 })
 
 test('when navigating to a union of routes with search params including the root', () => {
@@ -2664,23 +2607,19 @@ test('when navigating to a union of routes with search params including the root
     { page: number } | {}
   >()
 
-  defaultRouterSearch
-    .parameter(0)
-    .toEqualTypeOf<{} | { page: number } | { page?: number }>()
+  defaultRouterSearch.parameter(0).toEqualTypeOf<{ page?: number }>()
 
-  defaultRouterObjectsSearch
-    .parameter(0)
-    .toEqualTypeOf<{} | { page: number } | { page?: number }>()
+  defaultRouterObjectsSearch.parameter(0).toEqualTypeOf<{ page?: number }>()
 
   routerAlwaysTrailingSlashesLinkSearch
     .parameter(0)
-    .toEqualTypeOf<{} | { page: number } | { page?: number }>()
+    .toEqualTypeOf<{ page?: number }>()
 
   routerNeverTrailingSlashesLinkSearch
     .parameter(0)
-    .toEqualTypeOf<{} | { page: number } | { page?: number }>()
+    .toEqualTypeOf<{ page?: number }>()
 
   routerPreserveTrailingSlashesLinkSearch
     .parameter(0)
-    .toEqualTypeOf<{} | { page: number } | { page?: number }>()
+    .toEqualTypeOf<{ page?: number }>()
 })