@tanstack/react-router 1.8.4 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/cjs/Matches.cjs +1 -1
  2. package/dist/cjs/Matches.cjs.map +1 -1
  3. package/dist/cjs/Matches.d.cts +16 -11
  4. package/dist/cjs/RouterProvider.cjs.map +1 -1
  5. package/dist/cjs/RouterProvider.d.cts +1 -1
  6. package/dist/cjs/fileRoute.cjs +48 -1
  7. package/dist/cjs/fileRoute.cjs.map +1 -1
  8. package/dist/cjs/fileRoute.d.cts +40 -2
  9. package/dist/cjs/index.cjs +7 -0
  10. package/dist/cjs/index.cjs.map +1 -1
  11. package/dist/cjs/route.cjs +13 -1
  12. package/dist/cjs/route.cjs.map +1 -1
  13. package/dist/cjs/route.d.cts +76 -4
  14. package/dist/cjs/router.cjs +44 -18
  15. package/dist/cjs/router.cjs.map +1 -1
  16. package/dist/cjs/router.d.cts +7 -3
  17. package/dist/cjs/useParams.cjs.map +1 -1
  18. package/dist/cjs/useParams.d.cts +3 -2
  19. package/dist/cjs/useSearch.cjs.map +1 -1
  20. package/dist/cjs/useSearch.d.cts +3 -3
  21. package/dist/cjs/utils.cjs.map +1 -1
  22. package/dist/cjs/utils.d.cts +2 -1
  23. package/dist/esm/Matches.d.ts +16 -11
  24. package/dist/esm/Matches.js +1 -1
  25. package/dist/esm/Matches.js.map +1 -1
  26. package/dist/esm/RouterProvider.d.ts +1 -1
  27. package/dist/esm/RouterProvider.js.map +1 -1
  28. package/dist/esm/fileRoute.d.ts +40 -2
  29. package/dist/esm/fileRoute.js +50 -3
  30. package/dist/esm/fileRoute.js.map +1 -1
  31. package/dist/esm/index.js +10 -3
  32. package/dist/esm/route.d.ts +76 -4
  33. package/dist/esm/route.js +13 -1
  34. package/dist/esm/route.js.map +1 -1
  35. package/dist/esm/router.d.ts +7 -3
  36. package/dist/esm/router.js +44 -18
  37. package/dist/esm/router.js.map +1 -1
  38. package/dist/esm/useParams.d.ts +3 -2
  39. package/dist/esm/useParams.js.map +1 -1
  40. package/dist/esm/useSearch.d.ts +3 -3
  41. package/dist/esm/useSearch.js.map +1 -1
  42. package/dist/esm/utils.d.ts +2 -1
  43. package/dist/esm/utils.js.map +1 -1
  44. package/package.json +1 -1
  45. package/src/Matches.tsx +50 -17
  46. package/src/RouterProvider.tsx +7 -2
  47. package/src/fileRoute.ts +113 -6
  48. package/src/route.ts +226 -20
  49. package/src/router.ts +54 -10
  50. package/src/useParams.tsx +7 -4
  51. package/src/useSearch.tsx +12 -7
  52. package/src/utils.ts +2 -1
package/src/Matches.tsx CHANGED
@@ -7,6 +7,8 @@ import { useRouter } from './useRouter'
7
7
  import { ResolveRelativePath, ToOptions } from './link'
8
8
  import { AnyRoute, ReactNode, RootSearchSchema } from './route'
9
9
  import {
10
+ AllParams,
11
+ FullSearchSchema,
10
12
  ParseRoute,
11
13
  RouteById,
12
14
  RouteByPath,
@@ -14,18 +16,21 @@ import {
14
16
  RoutePaths,
15
17
  } from './routeInfo'
16
18
  import { RegisteredRouter, RouterState } from './router'
17
- import { DeepOptional, NoInfer, StrictOrFrom, pick } from './utils'
19
+ import { DeepOptional, Expand, NoInfer, StrictOrFrom, pick } from './utils'
18
20
 
19
21
  export const matchContext = React.createContext<string | undefined>(undefined)
20
22
 
21
23
  export interface RouteMatch<
22
- TRouteTree extends AnyRoute = AnyRoute,
24
+ TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
23
25
  TRouteId extends RouteIds<TRouteTree> = ParseRoute<TRouteTree>['id'],
26
+ TReturnIntersection extends boolean = false,
24
27
  > {
25
28
  id: string
26
29
  routeId: TRouteId
27
30
  pathname: string
28
- params: RouteById<TRouteTree, TRouteId>['types']['allParams']
31
+ params: TReturnIntersection extends false
32
+ ? RouteById<TRouteTree, TRouteId>['types']['allParams']
33
+ : Expand<Partial<AllParams<TRouteTree>>>
29
34
  status: 'pending' | 'success' | 'error'
30
35
  isFetching: boolean
31
36
  showPending: boolean
@@ -37,10 +42,14 @@ export interface RouteMatch<
37
42
  loaderData?: RouteById<TRouteTree, TRouteId>['types']['loaderData']
38
43
  routeContext: RouteById<TRouteTree, TRouteId>['types']['routeContext']
39
44
  context: RouteById<TRouteTree, TRouteId>['types']['allContext']
40
- search: Exclude<
41
- RouteById<TRouteTree, TRouteId>['types']['fullSearchSchema'],
42
- RootSearchSchema
43
- >
45
+ search: TReturnIntersection extends false
46
+ ? Exclude<
47
+ RouteById<TRouteTree, TRouteId>['types']['fullSearchSchema'],
48
+ RootSearchSchema
49
+ >
50
+ : Expand<
51
+ Partial<Omit<FullSearchSchema<TRouteTree>, keyof RootSearchSchema>>
52
+ >
44
53
  fetchCount: number
45
54
  abortController: AbortController
46
55
  cause: 'preload' | 'enter' | 'stay'
@@ -48,6 +57,9 @@ export interface RouteMatch<
48
57
  preload: boolean
49
58
  invalid: boolean
50
59
  pendingPromise?: Promise<void>
60
+ meta?: JSX.IntrinsicElements['meta'][]
61
+ links?: JSX.IntrinsicElements['link'][]
62
+ scripts?: JSX.IntrinsicElements['script'][]
51
63
  }
52
64
 
53
65
  export type AnyRouteMatch = RouteMatch<any, any>
@@ -298,7 +310,9 @@ export function MatchRoute<
298
310
  return !!params ? props.children : null
299
311
  }
300
312
 
301
- export function getRenderedMatches(state: RouterState) {
313
+ export function getRenderedMatches<
314
+ TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
315
+ >(state: RouterState<TRouteTree>) {
302
316
  return state.pendingMatches?.some((d) => d.showPending)
303
317
  ? state.pendingMatches
304
318
  : state.matches
@@ -307,10 +321,11 @@ export function getRenderedMatches(state: RouterState) {
307
321
  export function useMatch<
308
322
  TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
309
323
  TFrom extends RouteIds<TRouteTree> = RouteIds<TRouteTree>,
310
- TRouteMatchState = RouteMatch<TRouteTree, TFrom>,
324
+ TReturnIntersection extends boolean = false,
325
+ TRouteMatchState = RouteMatch<TRouteTree, TFrom, TReturnIntersection>,
311
326
  TSelected = TRouteMatchState,
312
327
  >(
313
- opts: StrictOrFrom<TFrom> & {
328
+ opts: StrictOrFrom<TFrom, TReturnIntersection> & {
314
329
  select?: (match: TRouteMatchState) => TSelected
315
330
  },
316
331
  ): TSelected {
@@ -364,26 +379,44 @@ export function useMatch<
364
379
  return matchSelection as any
365
380
  }
366
381
 
367
- export function useMatches<T = RouteMatch[]>(opts?: {
368
- select?: (matches: RouteMatch[]) => T
382
+ export function useMatches<
383
+ TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
384
+ TRouteId extends RouteIds<TRouteTree> = ParseRoute<TRouteTree>['id'],
385
+ TReturnIntersection extends boolean = false,
386
+ TRouteMatch = RouteMatch<TRouteTree, TRouteId, TReturnIntersection>,
387
+ T = TRouteMatch[],
388
+ >(opts?: {
389
+ select?: (matches: TRouteMatch[]) => T
390
+ experimental_returnIntersection?: TReturnIntersection
369
391
  }): T {
370
392
  return useRouterState({
371
393
  select: (state) => {
372
- let matches = getRenderedMatches(state)
373
- return opts?.select ? opts.select(matches) : (matches as T)
394
+ const matches = getRenderedMatches(state)
395
+ return opts?.select
396
+ ? opts.select(matches as TRouteMatch[])
397
+ : (matches as T)
374
398
  },
375
399
  })
376
400
  }
377
401
 
378
- export function useParentMatches<T = RouteMatch[]>(opts?: {
379
- select?: (matches: RouteMatch[]) => T
402
+ export function useParentMatches<
403
+ TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
404
+ TRouteId extends RouteIds<TRouteTree> = ParseRoute<TRouteTree>['id'],
405
+ TReturnIntersection extends boolean = false,
406
+ TRouteMatch = RouteMatch<TRouteTree, TRouteId, TReturnIntersection>,
407
+ T = TRouteMatch[],
408
+ >(opts?: {
409
+ select?: (matches: TRouteMatch[]) => T
410
+ experimental_returnIntersection?: TReturnIntersection
380
411
  }): T {
381
412
  const contextMatchId = React.useContext(matchContext)
382
413
 
383
414
  return useMatches({
384
415
  select: (matches) => {
385
416
  matches = matches.slice(matches.findIndex((d) => d.id === contextMatchId))
386
- return opts?.select ? opts.select(matches) : (matches as T)
417
+ return opts?.select
418
+ ? opts.select(matches as TRouteMatch[])
419
+ : (matches as T)
387
420
  },
388
421
  })
389
422
  }
@@ -43,8 +43,13 @@ export type NavigateFn<TRouteTree extends AnyRoute> = <
43
43
  opts: NavigateOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo>,
44
44
  ) => Promise<void>
45
45
 
46
- export type BuildLocationFn<TRouteTree extends AnyRoute> = (
47
- opts: ToOptions<TRouteTree> & {
46
+ export type BuildLocationFn<TRouteTree extends AnyRoute> = <
47
+ TFrom extends RoutePaths<TRouteTree> | string = RoutePaths<TRouteTree>,
48
+ TTo extends string = '',
49
+ TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom,
50
+ TMaskTo extends string = '',
51
+ >(
52
+ opts: ToOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> & {
48
53
  leaveParams?: boolean
49
54
  },
50
55
  ) => ParsedLocation
package/src/fileRoute.ts CHANGED
@@ -10,6 +10,7 @@ import {
10
10
  RouteOptions,
11
11
  UpdatableRouteOptions,
12
12
  Route,
13
+ createRoute,
13
14
  RootRouteId,
14
15
  TrimPathLeft,
15
16
  RouteConstraints,
@@ -17,8 +18,14 @@ import {
17
18
  SearchSchemaInput,
18
19
  LoaderFnContext,
19
20
  RouteLoaderFn,
21
+ AnyPathParams,
22
+ AnySearchSchema,
20
23
  } from './route'
21
24
  import { Assign, Expand, IsAny } from './utils'
25
+ import { useMatch, useLoaderDeps, useLoaderData } from './Matches'
26
+ import { useSearch } from './useSearch'
27
+ import { useParams } from './useParams'
28
+ import warning from 'tiny-warning'
22
29
 
23
30
  export interface FileRoutesByPath {
24
31
  // '/': {
@@ -77,12 +84,34 @@ export type ResolveFilePath<
77
84
  export type FileRoutePath<
78
85
  TParentRoute extends AnyRoute,
79
86
  TFilePath extends string,
80
- > = ResolveFilePath<TParentRoute, TFilePath> extends `_${infer _}`
81
- ? ''
82
- : ResolveFilePath<TParentRoute, TFilePath> extends `/_${infer _}`
87
+ > =
88
+ ResolveFilePath<TParentRoute, TFilePath> extends `_${infer _}`
83
89
  ? ''
84
- : ResolveFilePath<TParentRoute, TFilePath>
90
+ : ResolveFilePath<TParentRoute, TFilePath> extends `/_${infer _}`
91
+ ? ''
92
+ : ResolveFilePath<TParentRoute, TFilePath>
85
93
 
94
+ export function createFileRoute<
95
+ TFilePath extends keyof FileRoutesByPath,
96
+ TParentRoute extends AnyRoute = FileRoutesByPath[TFilePath]['parentRoute'],
97
+ TId extends RouteConstraints['TId'] = TFilePath,
98
+ TPath extends RouteConstraints['TPath'] = FileRoutePath<
99
+ TParentRoute,
100
+ TFilePath
101
+ >,
102
+ TFullPath extends RouteConstraints['TFullPath'] = ResolveFullPath<
103
+ TParentRoute,
104
+ RemoveUnderScores<TPath>
105
+ >,
106
+ >(path: TFilePath) {
107
+ return new FileRoute<TFilePath, TParentRoute, TId, TPath, TFullPath>(path)
108
+ .createRoute
109
+ }
110
+
111
+ /**
112
+ @deprecated It's no longer recommended to use the `FileRoute` class directly.
113
+ Instead, use `createFileRoute('/path/to/file')(options)` to create a file route.
114
+ */
86
115
  export class FileRoute<
87
116
  TFilePath extends keyof FileRoutesByPath,
88
117
  TParentRoute extends AnyRoute = FileRoutesByPath[TFilePath]['parentRoute'],
@@ -163,7 +192,7 @@ export class FileRoute<
163
192
  >,
164
193
  'getParentRoute' | 'path' | 'id'
165
194
  > &
166
- UpdatableRouteOptions<TFullSearchSchema>,
195
+ UpdatableRouteOptions<TFullSearchSchema, TLoaderData>,
167
196
  ): Route<
168
197
  TParentRoute,
169
198
  TPath,
@@ -186,12 +215,21 @@ export class FileRoute<
186
215
  TChildren,
187
216
  TRouteTree
188
217
  > => {
189
- const route = new Route(options as any)
218
+ warning(
219
+ false,
220
+ 'FileRoute is deprecated and will be removed in the next major version. Use the createFileRoute(path)(options) function instead.',
221
+ )
222
+ const route = createRoute(options as any)
190
223
  ;(route as any).isRoot = false
191
224
  return route as any
192
225
  }
193
226
  }
194
227
 
228
+ /**
229
+ @deprecated It's recommended not to split loaders into separate files.
230
+ Instead, place the loader function in the the main route file, inside the
231
+ `createFileRoute('/path/to/file)(options)` options.
232
+ */
195
233
  export function FileRouteLoader<
196
234
  TFilePath extends keyof FileRoutesByPath,
197
235
  TRoute extends FileRoutesByPath[TFilePath]['preLoaderRoute'],
@@ -212,5 +250,74 @@ export function FileRouteLoader<
212
250
  TRoute['types']['routeContext'],
213
251
  NoInfer<TLoaderData>
214
252
  > {
253
+ warning(
254
+ false,
255
+ `FileRouteLoader is deprecated and will be removed in the next major version. Please place the loader function in the the main route file, inside the \`createFileRoute('/path/to/file')(options)\` options`,
256
+ )
215
257
  return (loaderFn) => loaderFn
216
258
  }
259
+
260
+ export type LazyRouteOptions = Pick<
261
+ UpdatableRouteOptions<AnySearchSchema, any>,
262
+ 'component' | 'errorComponent' | 'pendingComponent'
263
+ >
264
+
265
+ export class LazyRoute<TRoute extends AnyRoute> {
266
+ options: {
267
+ id: string
268
+ } & LazyRouteOptions
269
+
270
+ constructor(
271
+ opts: {
272
+ id: string
273
+ } & LazyRouteOptions,
274
+ ) {
275
+ this.options = opts
276
+ }
277
+
278
+ useMatch = <TSelected = TRoute['types']['allContext']>(opts?: {
279
+ select?: (s: TRoute['types']['allContext']) => TSelected
280
+ }): TSelected => {
281
+ return useMatch({ select: opts?.select, from: this.options.id })
282
+ }
283
+
284
+ useRouteContext = <TSelected = TRoute['types']['allContext']>(opts?: {
285
+ select?: (s: TRoute['types']['allContext']) => TSelected
286
+ }): TSelected => {
287
+ return useMatch({
288
+ from: this.options.id,
289
+ select: (d: any) => (opts?.select ? opts.select(d.context) : d.context),
290
+ })
291
+ }
292
+
293
+ useSearch = <TSelected = TRoute['types']['fullSearchSchema']>(opts?: {
294
+ select?: (s: TRoute['types']['fullSearchSchema']) => TSelected
295
+ }): TSelected => {
296
+ return useSearch({ ...opts, from: this.options.id })
297
+ }
298
+
299
+ useParams = <TSelected = TRoute['types']['allParams']>(opts?: {
300
+ select?: (s: TRoute['types']['allParams']) => TSelected
301
+ }): TSelected => {
302
+ return useParams({ ...opts, from: this.options.id })
303
+ }
304
+
305
+ useLoaderDeps = <TSelected = TRoute['types']['loaderDeps']>(opts?: {
306
+ select?: (s: TRoute['types']['loaderDeps']) => TSelected
307
+ }): TSelected => {
308
+ return useLoaderDeps({ ...opts, from: this.options.id } as any)
309
+ }
310
+
311
+ useLoaderData = <TSelected = TRoute['types']['loaderData']>(opts?: {
312
+ select?: (s: TRoute['types']['loaderData']) => TSelected
313
+ }): TSelected => {
314
+ return useLoaderData({ ...opts, from: this.options.id } as any)
315
+ }
316
+ }
317
+
318
+ export function createLazyFileRoute<
319
+ TFilePath extends keyof FileRoutesByPath,
320
+ TRoute extends FileRoutesByPath[TFilePath]['preLoaderRoute'],
321
+ >(id: TFilePath) {
322
+ return (opts: LazyRouteOptions) => new LazyRoute<TRoute>({ id, ...opts })
323
+ }
package/src/route.ts CHANGED
@@ -9,15 +9,9 @@ import { RouteById, RouteIds, RoutePaths } from './routeInfo'
9
9
  import { AnyRouter, RegisteredRouter } from './router'
10
10
  import { useParams } from './useParams'
11
11
  import { useSearch } from './useSearch'
12
- import {
13
- Assign,
14
- Expand,
15
- IsAny,
16
- NoInfer,
17
- PickRequired,
18
- UnionToIntersection,
19
- } from './utils'
12
+ import { Assign, Expand, IsAny, NoInfer, UnionToIntersection } from './utils'
20
13
  import { BuildLocationFn, NavigateFn } from './RouterProvider'
14
+ import { LazyRoute } from '.'
21
15
 
22
16
  export const rootRouteId = '__root__' as const
23
17
  export type RootRouteId = typeof rootRouteId
@@ -81,7 +75,7 @@ export type RouteOptions<
81
75
  TLoaderDeps,
82
76
  TLoaderData
83
77
  > &
84
- UpdatableRouteOptions<NoInfer<TFullSearchSchema>>
78
+ UpdatableRouteOptions<NoInfer<TFullSearchSchema>, NoInfer<TLoaderData>>
85
79
 
86
80
  export type ParamsFallback<
87
81
  TPath extends string,
@@ -178,6 +172,7 @@ type BeforeLoadFn<
178
172
 
179
173
  export type UpdatableRouteOptions<
180
174
  TFullSearchSchema extends Record<string, any>,
175
+ TLoaderData extends any,
181
176
  > = {
182
177
  // test?: (args: TAllContext) => void
183
178
  // If true, this route will be matched as case-sensitive
@@ -188,6 +183,7 @@ export type UpdatableRouteOptions<
188
183
  component?: RouteComponent
189
184
  errorComponent?: false | null | ErrorRouteComponent
190
185
  pendingComponent?: RouteComponent
186
+ lazy?: () => Promise<LazyRoute<any>>
191
187
  pendingMs?: number
192
188
  pendingMinMs?: number
193
189
  staleTime?: number
@@ -206,8 +202,30 @@ export type UpdatableRouteOptions<
206
202
  onEnter?: (match: AnyRouteMatch) => void
207
203
  onStay?: (match: AnyRouteMatch) => void
208
204
  onLeave?: (match: AnyRouteMatch) => void
205
+ meta?: (ctx: { loaderData: TLoaderData }) => JSX.IntrinsicElements['meta'][]
206
+ links?: () => JSX.IntrinsicElements['link'][]
207
+ scripts?: () => JSX.IntrinsicElements['script'][]
209
208
  }
210
209
 
210
+ export type MetaDescriptor =
211
+ | { charSet: 'utf-8' }
212
+ | { title: string }
213
+ | { name: string; content: string }
214
+ | { property: string; content: string }
215
+ | { httpEquiv: string; content: string }
216
+ | { 'script:ld+json': LdJsonObject }
217
+ | { tagName: 'meta' | 'link'; [name: string]: string }
218
+ | { [name: string]: unknown }
219
+
220
+ type LdJsonObject = { [Key in string]: LdJsonValue } & {
221
+ [Key in string]?: LdJsonValue | undefined
222
+ }
223
+ type LdJsonArray = LdJsonValue[] | readonly LdJsonValue[]
224
+ type LdJsonPrimitive = string | number | boolean | null
225
+ type LdJsonValue = LdJsonPrimitive | LdJsonObject | LdJsonArray
226
+
227
+ export type RouteLinkEntry = {}
228
+
211
229
  export type ParseParamsOption<TPath extends string, TParams> = ParseParamsFn<
212
230
  TPath,
213
231
  TParams
@@ -455,6 +473,32 @@ export type RouteConstraints = {
455
473
  // }
456
474
  // }
457
475
 
476
+ export function getRouteApi<
477
+ TId extends RouteIds<RegisteredRouter['routeTree']>,
478
+ TRoute extends AnyRoute = RouteById<RegisteredRouter['routeTree'], TId>,
479
+ TFullSearchSchema extends Record<
480
+ string,
481
+ any
482
+ > = TRoute['types']['fullSearchSchema'],
483
+ TAllParams extends AnyPathParams = TRoute['types']['allParams'],
484
+ TAllContext extends Record<string, any> = TRoute['types']['allContext'],
485
+ TLoaderDeps extends Record<string, any> = TRoute['types']['loaderDeps'],
486
+ TLoaderData extends any = TRoute['types']['loaderData'],
487
+ >(id: TId) {
488
+ return new RouteApi<
489
+ TId,
490
+ TRoute,
491
+ TFullSearchSchema,
492
+ TAllParams,
493
+ TAllContext,
494
+ TLoaderDeps,
495
+ TLoaderData
496
+ >({ id })
497
+ }
498
+
499
+ /**
500
+ * @deprecated Use the `getRouteApi` function instead.
501
+ */
458
502
  export class RouteApi<
459
503
  TId extends RouteIds<RegisteredRouter['routeTree']>,
460
504
  TRoute extends AnyRoute = RouteById<RegisteredRouter['routeTree'], TId>,
@@ -513,6 +557,9 @@ export class RouteApi<
513
557
  }
514
558
  }
515
559
 
560
+ /**
561
+ * @deprecated Use the `createRoute` function instead.
562
+ */
516
563
  export class Route<
517
564
  TParentRoute extends RouteConstraints['TParentRoute'] = AnyRoute,
518
565
  TPath extends RouteConstraints['TPath'] = '/',
@@ -792,7 +839,7 @@ export class Route<
792
839
  >
793
840
  }
794
841
 
795
- update = (options: UpdatableRouteOptions<TFullSearchSchema>) => {
842
+ update = (options: UpdatableRouteOptions<TFullSearchSchema, TLoaderData>) => {
796
843
  Object.assign(this.options, options)
797
844
  return this
798
845
  }
@@ -838,6 +885,103 @@ export class Route<
838
885
  }
839
886
  }
840
887
 
888
+ export function createRoute<
889
+ TParentRoute extends RouteConstraints['TParentRoute'] = AnyRoute,
890
+ TPath extends RouteConstraints['TPath'] = '/',
891
+ TFullPath extends RouteConstraints['TFullPath'] = ResolveFullPath<
892
+ TParentRoute,
893
+ TPath
894
+ >,
895
+ TCustomId extends RouteConstraints['TCustomId'] = string,
896
+ TId extends RouteConstraints['TId'] = ResolveId<
897
+ TParentRoute,
898
+ TCustomId,
899
+ TPath
900
+ >,
901
+ TSearchSchemaInput extends RouteConstraints['TSearchSchema'] = {},
902
+ TSearchSchema extends RouteConstraints['TSearchSchema'] = {},
903
+ TSearchSchemaUsed extends Record<
904
+ string,
905
+ any
906
+ > = TSearchSchemaInput extends SearchSchemaInput
907
+ ? Omit<TSearchSchemaInput, keyof SearchSchemaInput>
908
+ : TSearchSchema,
909
+ TFullSearchSchemaInput extends Record<
910
+ string,
911
+ any
912
+ > = ResolveFullSearchSchemaInput<TParentRoute, TSearchSchemaUsed>,
913
+ TFullSearchSchema extends
914
+ RouteConstraints['TFullSearchSchema'] = ResolveFullSearchSchema<
915
+ TParentRoute,
916
+ TSearchSchema
917
+ >,
918
+ TParams extends RouteConstraints['TParams'] = Expand<
919
+ Record<ParsePathParams<TPath>, string>
920
+ >,
921
+ TAllParams extends RouteConstraints['TAllParams'] = ResolveAllParams<
922
+ TParentRoute,
923
+ TParams
924
+ >,
925
+ TRouteContextReturn extends RouteConstraints['TRouteContext'] = RouteContext,
926
+ TRouteContext extends RouteConstraints['TRouteContext'] = [
927
+ TRouteContextReturn,
928
+ ] extends [never]
929
+ ? RouteContext
930
+ : TRouteContextReturn,
931
+ TAllContext extends Expand<
932
+ Assign<IsAny<TParentRoute['types']['allContext'], {}>, TRouteContext>
933
+ > = Expand<
934
+ Assign<IsAny<TParentRoute['types']['allContext'], {}>, TRouteContext>
935
+ >,
936
+ TRouterContext extends RouteConstraints['TRouterContext'] = AnyContext,
937
+ TLoaderDeps extends Record<string, any> = {},
938
+ TLoaderData extends any = unknown,
939
+ TChildren extends RouteConstraints['TChildren'] = unknown,
940
+ TRouteTree extends RouteConstraints['TRouteTree'] = AnyRoute,
941
+ >(
942
+ options: RouteOptions<
943
+ TParentRoute,
944
+ TCustomId,
945
+ TPath,
946
+ TSearchSchemaInput,
947
+ TSearchSchema,
948
+ TSearchSchemaUsed,
949
+ TFullSearchSchemaInput,
950
+ TFullSearchSchema,
951
+ TParams,
952
+ TAllParams,
953
+ TRouteContextReturn,
954
+ TRouteContext,
955
+ TRouterContext,
956
+ TAllContext,
957
+ TLoaderDeps,
958
+ TLoaderData
959
+ >,
960
+ ) {
961
+ return new Route<
962
+ TParentRoute,
963
+ TPath,
964
+ TFullPath,
965
+ TCustomId,
966
+ TId,
967
+ TSearchSchemaInput,
968
+ TSearchSchema,
969
+ TSearchSchemaUsed,
970
+ TFullSearchSchemaInput,
971
+ TFullSearchSchema,
972
+ TParams,
973
+ TAllParams,
974
+ TRouteContextReturn,
975
+ TRouteContext,
976
+ TAllContext,
977
+ TRouterContext,
978
+ TLoaderDeps,
979
+ TLoaderData,
980
+ TChildren,
981
+ TRouteTree
982
+ >(options)
983
+ }
984
+
841
985
  export type AnyRootRoute = RootRoute<any, any, any, any, any, any, any, any>
842
986
 
843
987
  export function rootRouteWithContext<TRouterContext extends {}>() {
@@ -878,15 +1022,15 @@ export function rootRouteWithContext<TRouterContext extends {}>() {
878
1022
  | 'parseParams'
879
1023
  | 'stringifyParams'
880
1024
  >,
881
- ): RootRoute<
882
- TSearchSchemaInput,
883
- TSearchSchema,
884
- TSearchSchemaUsed,
885
- TRouteContextReturn,
886
- TRouteContext,
887
- TRouterContext
888
- > => {
889
- return new RootRoute(options) as any
1025
+ ) => {
1026
+ return createRootRoute<
1027
+ TSearchSchemaInput,
1028
+ TSearchSchema,
1029
+ TSearchSchemaUsed,
1030
+ TRouteContextReturn,
1031
+ TRouteContext,
1032
+ TRouterContext
1033
+ >(options as any)
890
1034
  }
891
1035
  }
892
1036
 
@@ -894,6 +1038,9 @@ export type RootSearchSchema = {
894
1038
  __TRootSearchSchema__: '__TRootSearchSchema__'
895
1039
  }
896
1040
 
1041
+ /**
1042
+ * @deprecated `RootRoute` is now an internal implementation detail. Use `createRootRoute()` instead.
1043
+ */
897
1044
  export class RootRoute<
898
1045
  TSearchSchemaInput extends Record<string, any> = RootSearchSchema,
899
1046
  TSearchSchema extends Record<string, any> = RootSearchSchema,
@@ -959,6 +1106,57 @@ export class RootRoute<
959
1106
  }
960
1107
  }
961
1108
 
1109
+ export function createRootRoute<
1110
+ TSearchSchemaInput extends Record<string, any> = RootSearchSchema,
1111
+ TSearchSchema extends Record<string, any> = RootSearchSchema,
1112
+ TSearchSchemaUsed extends Record<string, any> = RootSearchSchema,
1113
+ TRouteContextReturn extends RouteContext = RouteContext,
1114
+ TRouteContext extends RouteContext = [TRouteContextReturn] extends [never]
1115
+ ? RouteContext
1116
+ : TRouteContextReturn,
1117
+ TRouterContext extends {} = {},
1118
+ TLoaderDeps extends Record<string, any> = {},
1119
+ TLoaderData extends any = unknown,
1120
+ >(
1121
+ options?: Omit<
1122
+ RouteOptions<
1123
+ AnyRoute, // TParentRoute
1124
+ RootRouteId, // TCustomId
1125
+ '', // TPath
1126
+ TSearchSchemaInput, // TSearchSchemaInput
1127
+ TSearchSchema, // TSearchSchema
1128
+ TSearchSchemaUsed,
1129
+ TSearchSchemaUsed, // TFullSearchSchemaInput
1130
+ TSearchSchema, // TFullSearchSchema
1131
+ {}, // TParams
1132
+ {}, // TAllParams
1133
+ TRouteContextReturn, // TRouteContextReturn
1134
+ TRouteContext, // TRouteContext
1135
+ TRouterContext,
1136
+ Assign<TRouterContext, TRouteContext>, // TAllContext
1137
+ TLoaderDeps,
1138
+ TLoaderData
1139
+ >,
1140
+ | 'path'
1141
+ | 'id'
1142
+ | 'getParentRoute'
1143
+ | 'caseSensitive'
1144
+ | 'parseParams'
1145
+ | 'stringifyParams'
1146
+ >,
1147
+ ) {
1148
+ return new RootRoute<
1149
+ TSearchSchemaInput,
1150
+ TSearchSchema,
1151
+ TSearchSchemaUsed,
1152
+ TRouteContextReturn,
1153
+ TRouteContext,
1154
+ TRouterContext,
1155
+ TLoaderDeps,
1156
+ TLoaderData
1157
+ >(options)
1158
+ }
1159
+
962
1160
  export type ResolveFullPath<
963
1161
  TParentRoute extends AnyRoute,
964
1162
  TPath extends string,
@@ -1019,10 +1217,18 @@ export function createRouteMask<
1019
1217
  return opts as any
1020
1218
  }
1021
1219
 
1220
+ /**
1221
+ * @deprecated Use `ErrorComponentProps` instead.
1222
+ */
1022
1223
  export type ErrorRouteProps = {
1023
1224
  error: unknown
1024
1225
  info: { componentStack: string }
1025
1226
  }
1227
+
1228
+ export type ErrorComponentProps = {
1229
+ error: unknown
1230
+ info: { componentStack: string }
1231
+ }
1026
1232
  //
1027
1233
 
1028
1234
  export type ReactNode = any
@@ -1038,7 +1244,7 @@ export type AsyncRouteComponent<TProps> = SyncRouteComponent<TProps> & {
1038
1244
  export type RouteComponent<TProps = any> = SyncRouteComponent<TProps> &
1039
1245
  AsyncRouteComponent<TProps>
1040
1246
 
1041
- export type ErrorRouteComponent = RouteComponent<ErrorRouteProps>
1247
+ export type ErrorRouteComponent = RouteComponent<ErrorComponentProps>
1042
1248
 
1043
1249
  export class NotFoundRoute<
1044
1250
  TParentRoute extends AnyRootRoute,