@react-navigation/core 7.13.6 → 8.0.0-alpha.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 (157) hide show
  1. package/lib/module/BaseNavigationContainer.js +4 -9
  2. package/lib/module/BaseNavigationContainer.js.map +1 -1
  3. package/lib/module/NavigationIndependentTree.js +12 -7
  4. package/lib/module/NavigationIndependentTree.js.map +1 -1
  5. package/lib/module/NavigationProvider.js +49 -0
  6. package/lib/module/NavigationProvider.js.map +1 -0
  7. package/lib/module/PreventRemoveProvider.js +1 -1
  8. package/lib/module/PreventRemoveProvider.js.map +1 -1
  9. package/lib/module/SceneView.js.map +1 -1
  10. package/lib/module/StaticNavigation.js +32 -21
  11. package/lib/module/StaticNavigation.js.map +1 -1
  12. package/lib/module/createNavigationContainerRef.js.map +1 -1
  13. package/lib/module/getActionFromState.js +3 -2
  14. package/lib/module/getActionFromState.js.map +1 -1
  15. package/lib/module/getPathFromState.js +1 -1
  16. package/lib/module/getPathFromState.js.map +1 -1
  17. package/lib/module/getStateFromPath.js +3 -3
  18. package/lib/module/getStateFromPath.js.map +1 -1
  19. package/lib/module/index.js +1 -2
  20. package/lib/module/index.js.map +1 -1
  21. package/lib/module/theming/ThemeContext.js.map +1 -1
  22. package/lib/module/theming/ThemeProvider.js.map +1 -1
  23. package/lib/module/theming/useTheme.js +1 -1
  24. package/lib/module/theming/useTheme.js.map +1 -1
  25. package/lib/module/types.js +41 -0
  26. package/lib/module/types.js.map +1 -1
  27. package/lib/module/useChildListeners.js +2 -4
  28. package/lib/module/useChildListeners.js.map +1 -1
  29. package/lib/module/useDescriptors.js +5 -9
  30. package/lib/module/useDescriptors.js.map +1 -1
  31. package/lib/module/useEventEmitter.js +9 -20
  32. package/lib/module/useEventEmitter.js.map +1 -1
  33. package/lib/module/useFocusEvents.js +1 -1
  34. package/lib/module/useFocusEvents.js.map +1 -1
  35. package/lib/module/useNavigation.js +31 -8
  36. package/lib/module/useNavigation.js.map +1 -1
  37. package/lib/module/useNavigationBuilder.js +10 -12
  38. package/lib/module/useNavigationBuilder.js.map +1 -1
  39. package/lib/module/useNavigationCache.js +18 -11
  40. package/lib/module/useNavigationCache.js.map +1 -1
  41. package/lib/module/useNavigationHelpers.js +2 -14
  42. package/lib/module/useNavigationHelpers.js.map +1 -1
  43. package/lib/module/useNavigationState.js +42 -9
  44. package/lib/module/useNavigationState.js.map +1 -1
  45. package/lib/module/useOnAction.js +2 -7
  46. package/lib/module/useOnAction.js.map +1 -1
  47. package/lib/module/useOnGetState.js +1 -1
  48. package/lib/module/useOnGetState.js.map +1 -1
  49. package/lib/module/useOnPreventRemove.js +1 -1
  50. package/lib/module/useOnPreventRemove.js.map +1 -1
  51. package/lib/module/useRoute.js +23 -5
  52. package/lib/module/useRoute.js.map +1 -1
  53. package/lib/module/useScheduleUpdate.js +1 -2
  54. package/lib/module/useScheduleUpdate.js.map +1 -1
  55. package/lib/module/useSyncState.js +25 -9
  56. package/lib/module/useSyncState.js.map +1 -1
  57. package/lib/module/utilities.js +2 -0
  58. package/lib/module/utilities.js.map +1 -0
  59. package/lib/typescript/src/BaseNavigationContainer.d.ts.map +1 -1
  60. package/lib/typescript/src/NavigationIndependentTree.d.ts.map +1 -1
  61. package/lib/typescript/src/NavigationProvider.d.ts +44 -0
  62. package/lib/typescript/src/NavigationProvider.d.ts.map +1 -0
  63. package/lib/typescript/src/SceneView.d.ts +1 -1
  64. package/lib/typescript/src/SceneView.d.ts.map +1 -1
  65. package/lib/typescript/src/StaticNavigation.d.ts +231 -80
  66. package/lib/typescript/src/StaticNavigation.d.ts.map +1 -1
  67. package/lib/typescript/src/createNavigationContainerRef.d.ts +2 -2
  68. package/lib/typescript/src/createNavigationContainerRef.d.ts.map +1 -1
  69. package/lib/typescript/src/getStateFromPath.d.ts.map +1 -1
  70. package/lib/typescript/src/index.d.ts +2 -3
  71. package/lib/typescript/src/index.d.ts.map +1 -1
  72. package/lib/typescript/src/theming/ThemeContext.d.ts +2 -1
  73. package/lib/typescript/src/theming/ThemeContext.d.ts.map +1 -1
  74. package/lib/typescript/src/theming/ThemeProvider.d.ts +2 -1
  75. package/lib/typescript/src/theming/ThemeProvider.d.ts.map +1 -1
  76. package/lib/typescript/src/theming/useTheme.d.ts +1 -1
  77. package/lib/typescript/src/theming/useTheme.d.ts.map +1 -1
  78. package/lib/typescript/src/types.d.ts +188 -133
  79. package/lib/typescript/src/types.d.ts.map +1 -1
  80. package/lib/typescript/src/useChildListeners.d.ts.map +1 -1
  81. package/lib/typescript/src/useDescriptors.d.ts +27 -109
  82. package/lib/typescript/src/useDescriptors.d.ts.map +1 -1
  83. package/lib/typescript/src/useEventEmitter.d.ts.map +1 -1
  84. package/lib/typescript/src/useNavigation.d.ts +7 -5
  85. package/lib/typescript/src/useNavigation.d.ts.map +1 -1
  86. package/lib/typescript/src/useNavigationBuilder.d.ts +25 -114
  87. package/lib/typescript/src/useNavigationBuilder.d.ts.map +1 -1
  88. package/lib/typescript/src/useNavigationCache.d.ts +8 -22
  89. package/lib/typescript/src/useNavigationCache.d.ts.map +1 -1
  90. package/lib/typescript/src/useNavigationContainerRef.d.ts +2 -2
  91. package/lib/typescript/src/useNavigationContainerRef.d.ts.map +1 -1
  92. package/lib/typescript/src/useNavigationHelpers.d.ts +3 -11
  93. package/lib/typescript/src/useNavigationHelpers.d.ts.map +1 -1
  94. package/lib/typescript/src/useNavigationState.d.ts +10 -3
  95. package/lib/typescript/src/useNavigationState.d.ts.map +1 -1
  96. package/lib/typescript/src/useOnAction.d.ts.map +1 -1
  97. package/lib/typescript/src/useRoute.d.ts +8 -2
  98. package/lib/typescript/src/useRoute.d.ts.map +1 -1
  99. package/lib/typescript/src/useRouteCache.d.ts +12 -3
  100. package/lib/typescript/src/useRouteCache.d.ts.map +1 -1
  101. package/lib/typescript/src/useScheduleUpdate.d.ts.map +1 -1
  102. package/lib/typescript/src/useSyncState.d.ts.map +1 -1
  103. package/lib/typescript/src/utilities.d.ts +99 -0
  104. package/lib/typescript/src/utilities.d.ts.map +1 -0
  105. package/package.json +10 -10
  106. package/src/BaseNavigationContainer.tsx +3 -9
  107. package/src/NavigationIndependentTree.tsx +17 -9
  108. package/src/NavigationProvider.tsx +64 -0
  109. package/src/PreventRemoveProvider.tsx +1 -1
  110. package/src/SceneView.tsx +1 -7
  111. package/src/StaticNavigation.tsx +372 -134
  112. package/src/createNavigationContainerRef.tsx +2 -1
  113. package/src/getActionFromState.tsx +4 -2
  114. package/src/getPathFromState.tsx +6 -5
  115. package/src/getStateFromPath.tsx +11 -11
  116. package/src/index.tsx +8 -4
  117. package/src/theming/ThemeContext.tsx +3 -3
  118. package/src/theming/ThemeProvider.tsx +2 -1
  119. package/src/theming/useTheme.tsx +1 -1
  120. package/src/types.tsx +392 -243
  121. package/src/useChildListeners.tsx +3 -2
  122. package/src/useDescriptors.tsx +11 -17
  123. package/src/useEventEmitter.tsx +14 -31
  124. package/src/useFocusEvents.tsx +1 -1
  125. package/src/useNavigation.tsx +57 -14
  126. package/src/useNavigationBuilder.tsx +10 -13
  127. package/src/useNavigationCache.tsx +40 -18
  128. package/src/useNavigationContainerRef.tsx +2 -2
  129. package/src/useNavigationHelpers.tsx +2 -19
  130. package/src/useNavigationState.tsx +90 -19
  131. package/src/useOnAction.tsx +1 -12
  132. package/src/useOnGetState.tsx +1 -1
  133. package/src/useOnPreventRemove.tsx +1 -1
  134. package/src/useRoute.tsx +52 -7
  135. package/src/useScheduleUpdate.tsx +1 -2
  136. package/src/useSyncState.tsx +28 -13
  137. package/src/utilities.tsx +122 -0
  138. package/lib/module/DeprecatedNavigationInChildContext.js +0 -9
  139. package/lib/module/DeprecatedNavigationInChildContext.js.map +0 -1
  140. package/lib/module/NavigationContext.js +0 -8
  141. package/lib/module/NavigationContext.js.map +0 -1
  142. package/lib/module/NavigationRouteContext.js +0 -9
  143. package/lib/module/NavigationRouteContext.js.map +0 -1
  144. package/lib/module/useClientLayoutEffect.js +0 -9
  145. package/lib/module/useClientLayoutEffect.js.map +0 -1
  146. package/lib/typescript/src/DeprecatedNavigationInChildContext.d.ts +0 -6
  147. package/lib/typescript/src/DeprecatedNavigationInChildContext.d.ts.map +0 -1
  148. package/lib/typescript/src/NavigationContext.d.ts +0 -8
  149. package/lib/typescript/src/NavigationContext.d.ts.map +0 -1
  150. package/lib/typescript/src/NavigationRouteContext.d.ts +0 -7
  151. package/lib/typescript/src/NavigationRouteContext.d.ts.map +0 -1
  152. package/lib/typescript/src/useClientLayoutEffect.d.ts +0 -6
  153. package/lib/typescript/src/useClientLayoutEffect.d.ts.map +0 -1
  154. package/src/DeprecatedNavigationInChildContext.tsx +0 -6
  155. package/src/NavigationContext.tsx +0 -11
  156. package/src/NavigationRouteContext.tsx +0 -9
  157. package/src/useClientLayoutEffect.tsx +0 -10
package/src/types.tsx CHANGED
@@ -10,27 +10,68 @@ import type {
10
10
  } from '@react-navigation/routers';
11
11
  import type * as React from 'react';
12
12
 
13
- declare global {
14
- // eslint-disable-next-line @typescript-eslint/no-namespace
15
- namespace ReactNavigation {
16
- // eslint-disable-next-line @typescript-eslint/no-empty-interface
17
- interface RootParamList {}
18
-
19
- // eslint-disable-next-line @typescript-eslint/no-empty-interface
20
- interface Theme {}
21
- }
22
- }
23
-
24
- type Keyof<T extends {}> = Extract<keyof T, string>;
13
+ import type {
14
+ FlatType,
15
+ KeyOf,
16
+ NotUndefined,
17
+ UnionToIntersection,
18
+ } from './utilities';
19
+
20
+ /**
21
+ * Root navigator used in the app.
22
+ * It's used for the global types in the app.
23
+ * Users need to use module augmentation to add their navigator type:
24
+ *
25
+ * ```ts
26
+ * // Navigator created with static or dynamic API
27
+ * const RootStack = createStackNavigator({
28
+ * // ...
29
+ * });
30
+ *
31
+ * type RootStackType = typeof RootStack;
32
+ *
33
+ * declare module '@react-navigation/core' {
34
+ * interface RootNavigator extends RootStackType {}
35
+ * }
36
+ * ```
37
+ */
38
+ // eslint-disable-next-line @typescript-eslint/no-empty-interface
39
+ export interface RootNavigator {}
40
+
41
+ /**
42
+ * Theme object for the navigation components.
43
+ * Custom properties can be added using declaration merging:
44
+ *
45
+ * ```ts
46
+ * declare module '@react-navigation/core' {
47
+ * interface Theme extends NativeTheme {
48
+ * myCustomProperty: string;
49
+ * }
50
+ * }
51
+ * ```
52
+ */
53
+ // eslint-disable-next-line @typescript-eslint/no-empty-interface
54
+ export interface Theme {}
55
+
56
+ export type RootParamList =
57
+ RootNavigator extends TypedNavigatorInternal<
58
+ infer ParamList,
59
+ any,
60
+ any,
61
+ any,
62
+ any,
63
+ any
64
+ >
65
+ ? ParamList
66
+ : {};
25
67
 
26
68
  export type DefaultNavigatorOptions<
27
69
  ParamList extends ParamListBase,
28
- NavigatorID extends string | undefined,
29
70
  State extends NavigationState,
30
71
  ScreenOptions extends {},
31
72
  EventMap extends EventMapBase,
32
73
  Navigation,
33
- > = DefaultRouterOptions<Keyof<ParamList>> & {
74
+ > = DefaultRouterOptions<KeyOf<ParamList>> & {
34
75
  /**
35
76
  * Children React Elements to extract the route configuration from.
36
77
  * Only `Screen`, `Group` and `React.Fragment` are supported as children.
@@ -51,7 +92,6 @@ export type DefaultNavigatorOptions<
51
92
  NavigationProp<
52
93
  ParamList,
53
94
  keyof ParamList,
54
- string | undefined,
55
95
  State,
56
96
  ScreenOptions,
57
97
  EventMap
@@ -80,7 +120,7 @@ export type DefaultNavigatorOptions<
80
120
  | ((props: {
81
121
  route: RouteProp<ParamList>;
82
122
  navigation: Navigation;
83
- theme: ReactNavigation.Theme;
123
+ theme: Theme;
84
124
  }) => ScreenOptions);
85
125
 
86
126
  /**
@@ -102,7 +142,7 @@ export type DefaultNavigatorOptions<
102
142
  *
103
143
  * This must be a pure function and cannot reference outside dynamic variables.
104
144
  */
105
- UNSTABLE_router?: <Action extends NavigationAction>(
145
+ router?: <Action extends NavigationAction>(
106
146
  original: Router<State, Action>
107
147
  ) => Partial<Router<State, Action>>;
108
148
 
@@ -125,17 +165,8 @@ export type DefaultNavigatorOptions<
125
165
  * - Direct navigation is only handled for `NAVIGATE` actions.
126
166
  * - Unhandled state is restored only if the current state becomes invalid, i.e. it doesn't contain any currently defined screens.
127
167
  */
128
- UNSTABLE_routeNamesChangeBehavior?: 'firstMatch' | 'lastUnhandled';
129
- } & (NavigatorID extends string
130
- ? {
131
- /**
132
- * Optional ID for the navigator. Can be used with `navigation.getParent(id)` to refer to a parent.
133
- */
134
- id: NavigatorID;
135
- }
136
- : {
137
- id?: undefined;
138
- });
168
+ routeNamesChangeBehavior?: 'firstMatch' | 'lastUnhandled';
169
+ };
139
170
 
140
171
  export type EventMapBase = Record<
141
172
  string,
@@ -196,11 +227,11 @@ export type EventConsumer<EventMap extends EventMapBase> = {
196
227
  * @param type Type of the event (e.g. `focus`, `blur`)
197
228
  * @param callback Callback listener which is executed upon receiving the event.
198
229
  */
199
- addListener<EventName extends Keyof<EventMap>>(
230
+ addListener<EventName extends KeyOf<EventMap>>(
200
231
  type: EventName,
201
232
  callback: EventListenerCallback<EventMap, EventName>
202
233
  ): () => void;
203
- removeListener<EventName extends Keyof<EventMap>>(
234
+ removeListener<EventName extends KeyOf<EventMap>>(
204
235
  type: EventName,
205
236
  callback: EventListenerCallback<EventMap, EventName>
206
237
  ): void;
@@ -215,7 +246,7 @@ export type EventEmitter<EventMap extends EventMapBase> = {
215
246
  * @param [options.target] Key of the target route which should receive the event.
216
247
  * If not specified, all routes receive the event.
217
248
  */
218
- emit<EventName extends Keyof<EventMap>>(
249
+ emit<EventName extends KeyOf<EventMap>>(
219
250
  options: {
220
251
  type: EventName;
221
252
  target?: string;
@@ -311,39 +342,6 @@ type NavigationHelpersCommon<
311
342
  : never
312
343
  ): void;
313
344
 
314
- /**
315
- * Navigate to a route in current navigation tree.
316
- *
317
- * @deprecated Use `navigate` instead.
318
- *
319
- * @param screen Name of the route to navigate to.
320
- * @param [params] Params object for the route.
321
- */
322
- navigateDeprecated<RouteName extends keyof ParamList>(
323
- ...args: RouteName extends unknown
324
- ? undefined extends ParamList[RouteName]
325
- ? [screen: RouteName, params?: ParamList[RouteName]]
326
- : [screen: RouteName, params: ParamList[RouteName]]
327
- : never
328
- ): void;
329
-
330
- /**
331
- * Navigate to a route in current navigation tree.
332
- *
333
- * @deprecated Use `navigate` instead.
334
- *
335
- * @param options Object with `name` for the route to navigate to, and a `params` object.
336
- */
337
- navigateDeprecated<RouteName extends keyof ParamList>(
338
- options: RouteName extends unknown
339
- ? {
340
- name: RouteName;
341
- params: ParamList[RouteName];
342
- merge?: boolean;
343
- }
344
- : never
345
- ): void;
346
-
347
345
  /**
348
346
  * Preloads the route in current navigation tree.
349
347
  *
@@ -372,7 +370,10 @@ type NavigationHelpersCommon<
372
370
 
373
371
  /**
374
372
  * Check if the screen is focused. The method returns `true` if focused, `false` otherwise.
375
- * Note that this method doesn't re-render screen when the focus changes. So don't use it in `render`.
373
+ * Note that this method is non-reactive.
374
+ * It doesn't re-render the component when the result changes.
375
+ * So don't use it in `render`.
376
+ *
376
377
  * To get notified of focus changes, use `addListener('focus', cb)` and `addListener('blur', cb)`.
377
378
  * To conditionally render content based on focus state, use the `useIsFocused` hook.
378
379
  */
@@ -384,31 +385,30 @@ type NavigationHelpersCommon<
384
385
  */
385
386
  canGoBack(): boolean;
386
387
 
387
- /**
388
- * Returns the name of the navigator specified in the `name` prop.
389
- * If no name is specified, returns `undefined`.
390
- */
391
- getId(): string | undefined;
392
-
393
- /**
394
- * Returns the navigation helpers from a parent navigator based on the ID.
395
- * If an ID is provided, the navigation helper from the parent navigator with matching ID (including current) will be returned.
396
- * If no ID is provided, the navigation helper from the immediate parent navigator will be returned.
397
- *
398
- * @param id Optional ID of a parent navigator.
399
- */
400
- getParent<T = NavigationHelpers<ParamListBase> | undefined>(id?: string): T;
401
-
402
388
  /**
403
389
  * Returns the navigator's state.
404
- * Note that this method doesn't re-render screen when the result changes. So don't use it in `render`.
390
+ * Note that this method is non-reactive.
391
+ * It doesn't re-render the component when the result changes.
392
+ * So don't use it in `render`.
405
393
  */
406
394
  getState(): State;
407
395
  } & PrivateValueStore<[ParamList, unknown, unknown]>;
408
396
 
397
+ type ParamType<
398
+ ParamList extends {},
399
+ RouteName extends keyof ParamList | unknown,
400
+ IsPartial extends boolean = false,
401
+ > = RouteName extends keyof ParamList
402
+ ? ParamList[RouteName] extends undefined
403
+ ? undefined
404
+ : IsPartial extends true
405
+ ? Partial<ParamList[RouteName]>
406
+ : ParamList[RouteName]
407
+ : unknown;
408
+
409
409
  type NavigationHelpersRoute<
410
410
  ParamList extends {},
411
- RouteName extends keyof ParamList = Keyof<ParamList>,
411
+ RouteName extends keyof ParamList = KeyOf<ParamList>,
412
412
  > = {
413
413
  /**
414
414
  * Update the param object for the route.
@@ -416,22 +416,23 @@ type NavigationHelpersRoute<
416
416
  *
417
417
  * @param params Partial params object for the current route.
418
418
  */
419
- setParams(
420
- params: ParamList[RouteName] extends undefined
421
- ? undefined
422
- : Partial<ParamList[RouteName]>
423
- ): void;
419
+ setParams(params: ParamType<ParamList, RouteName, true>): void;
424
420
 
425
421
  /**
426
422
  * Replace the param object for the route
427
423
  *
428
424
  * @param params Params object for the current route.
429
425
  */
430
- replaceParams(
431
- params: ParamList[RouteName] extends undefined
432
- ? undefined
433
- : ParamList[RouteName]
434
- ): void;
426
+ replaceParams(params: ParamType<ParamList, RouteName>): void;
427
+
428
+ /**
429
+ * Push new params for the route.
430
+ * The params are not merged with previous params.
431
+ * This adds an entry to navigation history.
432
+ *
433
+ * @param params Params object for the current route.
434
+ */
435
+ pushParams(params: ParamType<ParamList, RouteName>): void;
435
436
  };
436
437
 
437
438
  export type NavigationHelpers<
@@ -458,20 +459,10 @@ export type NavigationContainerProps = {
458
459
  * Callback which is called when an action is not handled.
459
460
  */
460
461
  onUnhandledAction?: (action: Readonly<NavigationAction>) => void;
461
- /**
462
- * Whether child navigator should handle a navigation action.
463
- * The child navigator needs to be mounted before it can handle the action.
464
- * Defaults to `false`.
465
- *
466
- * This will be removed in the next major release.
467
- *
468
- * @deprecated Use nested navigation API instead
469
- */
470
- navigationInChildEnabled?: boolean;
471
462
  /**
472
463
  * Theme object for the UI elements.
473
464
  */
474
- theme?: ReactNavigation.Theme;
465
+ theme?: Theme;
475
466
  /**
476
467
  * Children elements to render.
477
468
  */
@@ -480,87 +471,90 @@ export type NavigationContainerProps = {
480
471
 
481
472
  export type NavigationProp<
482
473
  ParamList extends {},
483
- RouteName extends keyof ParamList = Keyof<ParamList>,
484
- NavigatorID extends string | undefined = string | undefined,
474
+ RouteName extends keyof ParamList = KeyOf<ParamList>,
485
475
  State extends NavigationState = NavigationState<ParamList>,
486
476
  ScreenOptions extends {} = {},
487
477
  EventMap extends EventMapBase = {},
478
+ ActionHelpers extends Record<string, (...args: any) => void> = {},
488
479
  > = Omit<NavigationHelpersCommon<ParamList, State>, 'getParent'> & {
489
- /**
490
- * Returns the navigation prop from a parent navigator based on the ID.
491
- * If an ID is provided, the navigation prop from the parent navigator with matching ID (including current) will be returned.
492
- * If no ID is provided, the navigation prop from the immediate parent navigator will be returned.
493
- *
494
- * @param id Optional ID of a parent navigator.
495
- */
496
- getParent<T = NavigationProp<ParamListBase> | undefined>(id?: NavigatorID): T;
497
-
498
480
  /**
499
481
  * Update the options for the route.
500
482
  * The options object will be shallow merged with default options object.
501
483
  *
502
- * @param update Options object or a callback which takes the options from navigator config and returns a new options object.
484
+ * @param options Partial options object for the current screen.
503
485
  */
504
486
  setOptions(options: Partial<ScreenOptions>): void;
487
+ /**
488
+ * Returns the navigation prop of the parent screen.
489
+ * If a route name is provided, the navigation prop from the parent screen with matching route name (including current) will be returned.
490
+ * If no route name is provided, the navigation prop from the immediate parent screen will be returned.
491
+ *
492
+ * @param routeName Optional route name of a parent screen.
493
+ */
494
+ getParent(
495
+ routeName: RouteName
496
+ ): NavigationProp<
497
+ ParamList,
498
+ RouteName,
499
+ State,
500
+ ScreenOptions,
501
+ EventMap,
502
+ ActionHelpers
503
+ >;
504
+ getParent(): NavigationProp<ParamListBase> | undefined;
505
505
  } & NavigationHelpersRoute<ParamList, RouteName> &
506
+ ActionHelpers &
506
507
  EventConsumer<EventMap & EventMapCore<State>> &
507
508
  PrivateValueStore<[ParamList, RouteName, EventMap]>;
508
509
 
509
510
  export type RouteProp<
510
511
  ParamList extends ParamListBase,
511
- RouteName extends keyof ParamList = Keyof<ParamList>,
512
+ RouteName extends keyof ParamList = KeyOf<ParamList>,
512
513
  > = Route<Extract<RouteName, string>, ParamList[RouteName]>;
513
514
 
514
515
  export type CompositeNavigationProp<
515
- A extends NavigationProp<ParamListBase, string, any, any, any>,
516
- B extends NavigationHelpersCommon<ParamListBase, any>,
517
- > = Omit<A & B, keyof NavigationProp<any>> &
518
- NavigationProp<
519
- /**
520
- * Param list from both navigation objects needs to be combined
521
- * For example, we should be able to navigate to screens in both A and B
522
- */
523
- (A extends NavigationHelpersCommon<infer T> ? T : never) &
524
- (B extends NavigationHelpersCommon<infer U> ? U : never),
525
- /**
526
- * The route name should refer to the route name specified in the first type
527
- * Ideally it should work for any of them, but it's not possible to infer that way
528
- */
529
- A extends NavigationProp<any, infer R> ? R : string,
530
- /**
531
- * ID from both navigation objects needs to be combined for `getParent`
532
- */
533
- | (A extends NavigationProp<any, any, infer I> ? I : never)
534
- | (B extends NavigationProp<any, any, infer J> ? J : never),
535
- /**
536
- * The type of state should refer to the state specified in the first type
537
- */
538
- A extends NavigationProp<any, any, any, infer S> ? S : NavigationState,
539
- /**
540
- * Screen options should refer to the options specified in the first type
541
- */
542
- A extends NavigationProp<any, any, any, any, infer O> ? O : {},
543
- /**
544
- * Event consumer config should refer to the config specified in the first type
545
- * This allows typechecking `addListener`/`removeListener`
546
- */
547
- A extends NavigationProp<any, any, any, any, any, infer E> ? E : {}
548
- >;
516
+ A extends NavigationProp<ParamListBase, any, any, any, any>,
517
+ B extends NavigationProp<ParamListBase, any, any, any, any>,
518
+ > = Omit<A & B, keyof NavigationProp<any, any, any, any, any>> &
519
+ Omit<
520
+ NavigationProp<
521
+ /**
522
+ * Param list from both navigation objects needs to be combined
523
+ * For example, we should be able to navigate to screens in both A and B
524
+ */
525
+ (A extends NavigationHelpersCommon<infer T> ? T : never) &
526
+ (B extends NavigationHelpersCommon<infer U> ? U : never),
527
+ /**
528
+ * The route name should refer to the route name specified in the first type
529
+ * Ideally it should work for any of them, but it's not possible to infer that way
530
+ */
531
+ A extends NavigationProp<any, infer R> ? R : string,
532
+ /**
533
+ * The type of state should refer to the state specified in the first type
534
+ */
535
+ A extends NavigationProp<any, any, infer S> ? S : NavigationState,
536
+ /**
537
+ * Screen options should refer to the options specified in the first type
538
+ */
539
+ A extends NavigationProp<any, any, any, infer O> ? O : {},
540
+ /**
541
+ * Event consumer config should refer to the config specified in the first type
542
+ * This allows typechecking `addListener`/`removeListener`
543
+ */
544
+ A extends NavigationProp<any, any, any, any, infer E> ? E : {}
545
+ >,
546
+ 'getParent'
547
+ > & {
548
+ getParent: A['getParent'] & B['getParent'];
549
+ };
549
550
 
550
551
  export type CompositeScreenProps<
551
552
  A extends {
552
- navigation: NavigationProp<
553
- ParamListBase,
554
- string,
555
- string | undefined,
556
- any,
557
- any,
558
- any
559
- >;
553
+ navigation: NavigationProp<ParamListBase, string, any, any, any>;
560
554
  route: RouteProp<ParamListBase>;
561
555
  },
562
556
  B extends {
563
- navigation: NavigationHelpersCommon<any, any>;
557
+ navigation: NavigationProp<ParamListBase, string, any, any, any>;
564
558
  },
565
559
  > = {
566
560
  navigation: CompositeNavigationProp<A['navigation'], B['navigation']>;
@@ -576,13 +570,13 @@ export type ScreenLayoutArgs<
576
570
  route: RouteProp<ParamList, RouteName>;
577
571
  options: ScreenOptions;
578
572
  navigation: Navigation;
579
- theme: ReactNavigation.Theme;
573
+ theme: Theme;
580
574
  children: React.ReactElement;
581
575
  };
582
576
 
583
577
  export type Descriptor<
584
578
  ScreenOptions extends {},
585
- Navigation extends NavigationProp<any, any, any, any, any, any>,
579
+ Navigation extends NavigationProp<any, any, any, any, any>,
586
580
  Route extends RouteProp<any, any>,
587
581
  > = {
588
582
  /**
@@ -686,7 +680,7 @@ export type RouteConfigProps<
686
680
  | ((props: {
687
681
  route: RouteProp<ParamList, RouteName>;
688
682
  navigation: Navigation;
689
- theme: ReactNavigation.Theme;
683
+ theme: Theme;
690
684
  }) => ScreenOptions);
691
685
 
692
686
  /**
@@ -762,7 +756,7 @@ export type RouteGroupConfig<
762
756
  | ((props: {
763
757
  route: RouteProp<ParamList, keyof ParamList>;
764
758
  navigation: Navigation;
765
- theme: ReactNavigation.Theme;
759
+ theme: Theme;
766
760
  }) => ScreenOptions);
767
761
 
768
762
  /**
@@ -834,20 +828,204 @@ export type NavigationContainerEventMap = {
834
828
  };
835
829
  };
836
830
 
837
- type NotUndefined<T> = T extends undefined ? never : T;
831
+ /**
832
+ * A stripped down NavigationProp if the navigator is not known.
833
+ *
834
+ * The hook can be used in `NavigationContainer` directly, not inside of a navigator.
835
+ * So navigator specific methods won't be available.
836
+ */
837
+ export type GenericNavigation<ParamList extends {}> = Omit<
838
+ NavigationProp<ParamList>,
839
+ 'getState' | 'setParams' | 'replaceParams' | 'pushParams' | 'setOptions'
840
+ > & {
841
+ /**
842
+ * Returns the navigator's state.
843
+ *
844
+ * This may return `undefined` if used outside of a navigator,
845
+ * as the navigator may not have rendered yet
846
+ */
847
+ getState(): NavigationState | undefined;
848
+
849
+ /**
850
+ * Update the param object for the route.
851
+ * The new params will be shallow merged with the old one.
852
+ *
853
+ * @param params Partial params object for the current route.
854
+ */
855
+ setParams(
856
+ // We don't know which route to set params for
857
+ params: unknown
858
+ ): void;
859
+
860
+ /**
861
+ * Replace the param object for the route
862
+ *
863
+ * @param params Params object for the current route.
864
+ */
865
+ replaceParams(
866
+ // We don't know which route to replace params for
867
+ params: unknown
868
+ ): void;
869
+
870
+ /**
871
+ * Push new params for the route.
872
+ * The params are not merged with previous params.
873
+ * This adds an entry to navigation history.
874
+ *
875
+ * @param params Params object for the current route.
876
+ */
877
+ pushParams(
878
+ // We don't know which route to push params for
879
+ params: unknown
880
+ ): void;
881
+
882
+ /**
883
+ * Update the options for the route.
884
+ * The options object will be shallow merged with default options object.
885
+ *
886
+ * @param options Partial options object for the current screen.
887
+ */
888
+ setOptions(
889
+ // We don't know which navigator to set options for
890
+ options: unknown
891
+ ): void;
892
+ };
893
+
894
+ export type RouteForName<
895
+ ParamList extends {},
896
+ RouteName extends string,
897
+ > = Extract<ParamListRoute<ParamList>, { name: RouteName }>;
838
898
 
839
- export type ParamListRoute<ParamList extends ParamListBase> = {
899
+ type ParamListRoute<ParamList extends {}> = {
840
900
  [RouteName in keyof ParamList]: NavigatorScreenParams<{}> extends ParamList[RouteName]
841
901
  ? NotUndefined<ParamList[RouteName]> extends NavigatorScreenParams<infer T>
842
- ? ParamListRoute<T>
843
- : Route<Extract<RouteName, string>, ParamList[RouteName]>
844
- : Route<Extract<RouteName, string>, ParamList[RouteName]>;
902
+ ? ParamListRoute<T> | RouteProp<ParamList, RouteName>
903
+ : RouteProp<ParamList, RouteName>
904
+ : RouteProp<ParamList, RouteName>;
845
905
  }[keyof ParamList];
846
906
 
847
907
  type MaybeParamListRoute<ParamList extends {}> = ParamList extends ParamListBase
848
908
  ? ParamListRoute<ParamList>
849
909
  : Route<string>;
850
910
 
911
+ type BasicNavigationComposite<
912
+ Navigation extends NavigationProp<any, any, any, any, any>,
913
+ Parent,
914
+ > =
915
+ Parent extends NavigationProp<any, any, any, any, any>
916
+ ? CompositeNavigationProp<Navigation, Parent>
917
+ : Navigation;
918
+
919
+ type BasicNavigationList<
920
+ ParamList extends {},
921
+ ExcludedRouteNames,
922
+ Parent extends NavigationProp<any, any, any, any, any> | undefined,
923
+ > = UnionToIntersection<
924
+ {
925
+ [RouteName in keyof ParamList]: (NavigatorScreenParams<{}> extends ParamList[RouteName]
926
+ ? NotUndefined<ParamList[RouteName]> extends NavigatorScreenParams<
927
+ infer T
928
+ >
929
+ ? BasicNavigationList<
930
+ T,
931
+ ExcludedRouteNames,
932
+ NavigationProp<ParamList, RouteName>
933
+ >
934
+ : {}
935
+ : {}) &
936
+ (RouteName extends ExcludedRouteNames
937
+ ? {}
938
+ : {
939
+ [Key in RouteName]: BasicNavigationComposite<
940
+ NavigationProp<ParamList, RouteName>,
941
+ Parent
942
+ >;
943
+ });
944
+ }[keyof ParamList]
945
+ >;
946
+
947
+ export type NavigationListForNavigator<Navigator> =
948
+ Navigator extends TypedNavigator<infer Bag, any>
949
+ ? Bag['NavigationList']
950
+ : Navigator extends PrivateValueStore<[any, infer NavigationList, any]>
951
+ ? NavigationList
952
+ : {};
953
+
954
+ export type NavigationListForNested<Navigator> = FlatType<
955
+ NavigationListForNestedInternal<Navigator> &
956
+ (Navigator extends TypedNavigator<infer Bag, any>
957
+ ? BasicNavigationList<
958
+ Bag['ParamList'],
959
+ keyof NavigationListForNestedInternal<Navigator>,
960
+ undefined
961
+ >
962
+ : Navigator extends PrivateValueStore<[infer ParamList, any, any]>
963
+ ? ParamList extends {}
964
+ ? BasicNavigationList<
965
+ ParamList,
966
+ keyof NavigationListForNestedInternal<Navigator>,
967
+ undefined
968
+ >
969
+ : {}
970
+ : {})
971
+ >;
972
+
973
+ type NavigationListForNestedInternal<Navigator> =
974
+ NavigationListForNavigator<Navigator> &
975
+ NavigationListForStaticConfig<
976
+ NavigationListForNavigator<Navigator>,
977
+ Navigator
978
+ >;
979
+
980
+ type NavigationListWithComposite<
981
+ Parent extends NavigationProp<any, any, any, any, any>,
982
+ NavigatorList extends Record<string, any>,
983
+ > = {
984
+ [K in keyof NavigatorList]: CompositeNavigationProp<NavigatorList[K], Parent>;
985
+ };
986
+
987
+ type NavigationListForStaticConfig<ParentList, Navigator> = Navigator extends {
988
+ readonly config: {
989
+ screens?: any;
990
+ groups?: any;
991
+ };
992
+ }
993
+ ? NavigationListForScreens<ParentList, Navigator['config']['screens']> &
994
+ NavigationListForGroups<ParentList, Navigator['config']['groups']>
995
+ : {};
996
+
997
+ type NavigationListForScreens<ParentList, Screens> = UnionToIntersection<
998
+ {
999
+ // Only check screens with static config to avoid overly-complex types
1000
+ // Otherwise TypeScript fails to load the types due to complexity
1001
+ [K in keyof Screens]: ParentList extends Record<K, any>
1002
+ ? Screens[K] extends { config: any }
1003
+ ? NavigationListWithComposite<
1004
+ ParentList[K],
1005
+ NavigationListForNested<Screens[K]>
1006
+ >
1007
+ : Screens[K] extends { screen: { config: any } }
1008
+ ? NavigationListWithComposite<
1009
+ ParentList[K],
1010
+ NavigationListForNested<Screens[K]['screen']>
1011
+ >
1012
+ : {}
1013
+ : {};
1014
+ }[keyof Screens]
1015
+ >;
1016
+
1017
+ type NavigationListForGroups<ParentList, Groups> =
1018
+ Groups extends Record<string, { screens: any }>
1019
+ ? UnionToIntersection<
1020
+ {
1021
+ [K in keyof Groups]: NavigationListForScreens<
1022
+ ParentList,
1023
+ Groups[K]['screens']
1024
+ >;
1025
+ }[keyof Groups]
1026
+ >
1027
+ : {};
1028
+
851
1029
  export type NavigationContainerRef<ParamList extends {}> =
852
1030
  NavigationHelpers<ParamList> &
853
1031
  EventConsumer<NavigationContainerEventMap> & {
@@ -892,27 +1070,8 @@ export type NavigationListBase<ParamList extends ParamListBase> = {
892
1070
  [RouteName in keyof ParamList]: unknown;
893
1071
  };
894
1072
 
895
- export type TypeBag<
896
- ParamList extends ParamListBase,
897
- NavigatorID extends string | undefined,
898
- State extends NavigationState,
899
- ScreenOptions extends {},
900
- EventMap extends EventMapBase,
901
- NavigationList extends NavigationListBase<ParamList>,
902
- Navigator extends React.ComponentType<any>,
903
- > = {
904
- ParamList: ParamList;
905
- NavigatorID: NavigatorID;
906
- State: State;
907
- ScreenOptions: ScreenOptions;
908
- EventMap: EventMap;
909
- NavigationList: NavigationList;
910
- Navigator: Navigator;
911
- };
912
-
913
1073
  export type NavigatorTypeBagBase = {
914
1074
  ParamList: {};
915
- NavigatorID: string | undefined;
916
1075
  State: NavigationState;
917
1076
  ScreenOptions: {};
918
1077
  EventMap: {};
@@ -920,41 +1079,22 @@ export type NavigatorTypeBagBase = {
920
1079
  Navigator: React.ComponentType<any>;
921
1080
  };
922
1081
 
923
- export type NavigatorTypeBag<
924
- ParamList extends ParamListBase,
925
- NavigatorID extends string | undefined,
926
- State extends NavigationState,
927
- ScreenOptions extends {},
928
- EventMap extends EventMapBase,
929
- NavigationList extends NavigationListBase<ParamList>,
930
- Navigator extends React.ComponentType<any>,
931
- > = {
932
- ParamList: ParamList;
933
- NavigatorID: NavigatorID;
934
- State: State;
935
- ScreenOptions: ScreenOptions;
936
- EventMap: EventMap;
937
- NavigationList: NavigationList;
938
- Navigator: Navigator;
939
- };
940
-
941
1082
  export type TypedNavigator<
942
1083
  Bag extends NavigatorTypeBagBase,
943
1084
  Config = unknown,
944
1085
  > = TypedNavigatorInternal<
945
1086
  Bag['ParamList'],
946
- Bag['NavigatorID'],
947
1087
  Bag['State'],
948
1088
  Bag['ScreenOptions'],
949
1089
  Bag['EventMap'],
950
1090
  Bag['NavigationList'],
951
1091
  Bag['Navigator']
952
1092
  > &
953
- (undefined extends Config ? {} : { config: Config });
1093
+ (undefined extends Config ? {} : { config: Config }) &
1094
+ PrivateValueStore<[Bag['ParamList'], Bag['NavigationList'], unknown]>;
954
1095
 
955
1096
  type TypedNavigatorInternal<
956
1097
  ParamList extends ParamListBase,
957
- NavigatorID extends string | undefined,
958
1098
  State extends NavigationState,
959
1099
  ScreenOptions extends {},
960
1100
  EventMap extends EventMapBase,
@@ -967,11 +1107,10 @@ type TypedNavigatorInternal<
967
1107
  Navigator: React.ComponentType<
968
1108
  Omit<
969
1109
  React.ComponentProps<Navigator>,
970
- keyof DefaultNavigatorOptions<any, any, any, any, any, any>
1110
+ keyof DefaultNavigatorOptions<any, any, any, any, any>
971
1111
  > &
972
1112
  DefaultNavigatorOptions<
973
1113
  ParamList,
974
- NavigatorID,
975
1114
  State,
976
1115
  ScreenOptions,
977
1116
  EventMap,
@@ -1031,7 +1170,15 @@ export type NavigatorScreenParams<ParamList extends {}> =
1031
1170
  };
1032
1171
  }[keyof ParamList];
1033
1172
 
1034
- type PathConfigAlias = {
1173
+ type ParseConfig<Params> = {
1174
+ [K in keyof Params]?: (value: string) => Params[K];
1175
+ };
1176
+
1177
+ type StringifyConfig<Params> = {
1178
+ [K in keyof Params]?: (value: Params[K]) => string;
1179
+ };
1180
+
1181
+ type PathConfigAlias<Params> = {
1035
1182
  /**
1036
1183
  * Path string to match against.
1037
1184
  * e.g. `/users/:id` will match `/users/1` and extract `id` param as `1`.
@@ -1054,40 +1201,42 @@ type PathConfigAlias = {
1054
1201
  * }
1055
1202
  * ```
1056
1203
  */
1057
- parse?: Record<string, (value: string) => any>;
1204
+ parse?: ParseConfig<Params>;
1058
1205
  };
1059
1206
 
1060
- export type PathConfig<ParamList extends {}> = Partial<PathConfigAlias> & {
1061
- /**
1062
- * An object mapping the param name to a function which converts the param value to a string.
1063
- * By default, all params are converted to strings using `String(value)`.
1064
- *
1065
- * @example
1066
- * ```js
1067
- * stringify: {
1068
- * date: (value) => value.toISOString()
1069
- * }
1070
- * ```
1071
- */
1072
- stringify?: Record<string, (value: any) => string>;
1073
- /**
1074
- * Additional path alias that will be matched to the same screen.
1075
- */
1076
- alias?: (string | PathConfigAlias)[];
1077
- /**
1078
- * Path configuration for child screens.
1079
- */
1080
- screens?: PathConfigMap<ParamList>;
1081
- /**
1082
- * Name of the initial route to use for the navigator when the path matches.
1083
- */
1084
- initialRouteName?: keyof ParamList;
1085
- };
1207
+ export type PathConfig<Params> = FlatType<
1208
+ Partial<PathConfigAlias<Params>> & {
1209
+ /**
1210
+ * An object mapping the param name to a function which converts the param value to a string.
1211
+ * By default, all params are converted to strings using `String(value)`.
1212
+ * Keys are constrained to valid param names when Params type is provided.
1213
+ *
1214
+ * @example
1215
+ * ```js
1216
+ * stringify: {
1217
+ * date: (value) => value.toISOString()
1218
+ * }
1219
+ * ```
1220
+ */
1221
+ stringify?: StringifyConfig<Params>;
1222
+ /**
1223
+ * Additional path alias that will be matched to the same screen.
1224
+ */
1225
+ alias?: (string | PathConfigAlias<Params>)[];
1226
+ } & (NonNullable<Params> extends NavigatorScreenParams<infer ParamList>
1227
+ ? {
1228
+ /**
1229
+ * Path configuration for child screens.
1230
+ */
1231
+ screens?: PathConfigMap<ParamList>;
1232
+ /**
1233
+ * Name of the initial route to use for the navigator when the path matches.
1234
+ */
1235
+ initialRouteName?: keyof ParamList;
1236
+ }
1237
+ : {})
1238
+ >;
1086
1239
 
1087
1240
  export type PathConfigMap<ParamList extends {}> = {
1088
- [RouteName in keyof ParamList]?: NonNullable<
1089
- ParamList[RouteName]
1090
- > extends NavigatorScreenParams<infer T extends {}>
1091
- ? string | PathConfig<T>
1092
- : string | Omit<PathConfig<{}>, 'screens' | 'initialRouteName'>;
1241
+ [RouteName in keyof ParamList]?: string | PathConfig<ParamList[RouteName]>;
1093
1242
  };