@react-navigation/core 8.0.0-alpha.23 → 8.0.0-alpha.25

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 (153) hide show
  1. package/lib/module/BaseNavigationContainer.js +5 -2
  2. package/lib/module/BaseNavigationContainer.js.map +1 -1
  3. package/lib/module/DataLoading.js +102 -0
  4. package/lib/module/DataLoading.js.map +1 -0
  5. package/lib/module/NavigationBuilderContext.js.map +1 -1
  6. package/lib/module/NavigationIndependentTree.js +7 -6
  7. package/lib/module/NavigationIndependentTree.js.map +1 -1
  8. package/lib/module/NavigationProvider.js +12 -12
  9. package/lib/module/NavigationProvider.js.map +1 -1
  10. package/lib/module/PreventRemoveContext.js.map +1 -1
  11. package/lib/module/PreventRemoveProvider.js +34 -24
  12. package/lib/module/PreventRemoveProvider.js.map +1 -1
  13. package/lib/module/StaticNavigation.js +15 -7
  14. package/lib/module/StaticNavigation.js.map +1 -1
  15. package/lib/module/StaticTreeContext.js +5 -0
  16. package/lib/module/StaticTreeContext.js.map +1 -0
  17. package/lib/module/checkSerializable.js +7 -9
  18. package/lib/module/checkSerializable.js.map +1 -1
  19. package/lib/module/createNavigationContainerRef.js +6 -8
  20. package/lib/module/createNavigationContainerRef.js.map +1 -1
  21. package/lib/module/createNavigatorFactory.js.map +1 -1
  22. package/lib/module/getActionFromState.js +11 -11
  23. package/lib/module/getActionFromState.js.map +1 -1
  24. package/lib/module/getPathFromState.js +125 -96
  25. package/lib/module/getPathFromState.js.map +1 -1
  26. package/lib/module/getPatternParts.js +2 -2
  27. package/lib/module/getPatternParts.js.map +1 -1
  28. package/lib/module/getStateFromPath.js +136 -78
  29. package/lib/module/getStateFromPath.js.map +1 -1
  30. package/lib/module/index.js +1 -0
  31. package/lib/module/index.js.map +1 -1
  32. package/lib/module/types.js +13 -0
  33. package/lib/module/types.js.map +1 -1
  34. package/lib/module/useEventEmitter.js +5 -2
  35. package/lib/module/useEventEmitter.js.map +1 -1
  36. package/lib/module/useKeyedChildListeners.js +4 -2
  37. package/lib/module/useKeyedChildListeners.js.map +1 -1
  38. package/lib/module/useNavigation.js +2 -15
  39. package/lib/module/useNavigation.js.map +1 -1
  40. package/lib/module/useNavigationBuilder.js +5 -21
  41. package/lib/module/useNavigationBuilder.js.map +1 -1
  42. package/lib/module/useNavigationCache.js +19 -14
  43. package/lib/module/useNavigationCache.js.map +1 -1
  44. package/lib/module/useNavigationHelpers.js +27 -9
  45. package/lib/module/useNavigationHelpers.js.map +1 -1
  46. package/lib/module/useNavigationState.js +69 -36
  47. package/lib/module/useNavigationState.js.map +1 -1
  48. package/lib/module/useOnAction.js +25 -3
  49. package/lib/module/useOnAction.js.map +1 -1
  50. package/lib/module/useOnPreventRemove.js +35 -24
  51. package/lib/module/useOnPreventRemove.js.map +1 -1
  52. package/lib/module/useOptionsGetters.js +3 -1
  53. package/lib/module/useOptionsGetters.js.map +1 -1
  54. package/lib/module/usePreventRemove.js +9 -2
  55. package/lib/module/usePreventRemove.js.map +1 -1
  56. package/lib/module/useRoute.js.map +1 -1
  57. package/lib/module/useRouteCache.js +14 -7
  58. package/lib/module/useRouteCache.js.map +1 -1
  59. package/lib/module/useScheduleUpdate.js +8 -8
  60. package/lib/module/useScheduleUpdate.js.map +1 -1
  61. package/lib/module/useSyncState.js +4 -1
  62. package/lib/module/useSyncState.js.map +1 -1
  63. package/lib/module/validatePathConfig.js +50 -37
  64. package/lib/module/validatePathConfig.js.map +1 -1
  65. package/lib/typescript/src/BaseNavigationContainer.d.ts.map +1 -1
  66. package/lib/typescript/src/DataLoading.d.ts +20 -0
  67. package/lib/typescript/src/DataLoading.d.ts.map +1 -0
  68. package/lib/typescript/src/NavigationBuilderContext.d.ts +2 -2
  69. package/lib/typescript/src/NavigationBuilderContext.d.ts.map +1 -1
  70. package/lib/typescript/src/NavigationProvider.d.ts +0 -1
  71. package/lib/typescript/src/NavigationProvider.d.ts.map +1 -1
  72. package/lib/typescript/src/PreventRemoveContext.d.ts +1 -0
  73. package/lib/typescript/src/PreventRemoveContext.d.ts.map +1 -1
  74. package/lib/typescript/src/PreventRemoveProvider.d.ts.map +1 -1
  75. package/lib/typescript/src/StaticNavigation.d.ts +68 -42
  76. package/lib/typescript/src/StaticNavigation.d.ts.map +1 -1
  77. package/lib/typescript/src/StaticTreeContext.d.ts +4 -0
  78. package/lib/typescript/src/StaticTreeContext.d.ts.map +1 -0
  79. package/lib/typescript/src/checkSerializable.d.ts +4 -2
  80. package/lib/typescript/src/checkSerializable.d.ts.map +1 -1
  81. package/lib/typescript/src/createNavigationContainerRef.d.ts.map +1 -1
  82. package/lib/typescript/src/createNavigatorFactory.d.ts +11 -5
  83. package/lib/typescript/src/createNavigatorFactory.d.ts.map +1 -1
  84. package/lib/typescript/src/getActionFromState.d.ts.map +1 -1
  85. package/lib/typescript/src/getPathFromState.d.ts.map +1 -1
  86. package/lib/typescript/src/getStateFromPath.d.ts.map +1 -1
  87. package/lib/typescript/src/index.d.ts +2 -1
  88. package/lib/typescript/src/index.d.ts.map +1 -1
  89. package/lib/typescript/src/types.d.ts +84 -29
  90. package/lib/typescript/src/types.d.ts.map +1 -1
  91. package/lib/typescript/src/useEventEmitter.d.ts +1 -1
  92. package/lib/typescript/src/useEventEmitter.d.ts.map +1 -1
  93. package/lib/typescript/src/useKeyedChildListeners.d.ts.map +1 -1
  94. package/lib/typescript/src/useNavigation.d.ts.map +1 -1
  95. package/lib/typescript/src/useNavigationBuilder.d.ts +1 -1
  96. package/lib/typescript/src/useNavigationBuilder.d.ts.map +1 -1
  97. package/lib/typescript/src/useNavigationCache.d.ts.map +1 -1
  98. package/lib/typescript/src/useNavigationHelpers.d.ts +3 -4
  99. package/lib/typescript/src/useNavigationHelpers.d.ts.map +1 -1
  100. package/lib/typescript/src/useNavigationState.d.ts +11 -1
  101. package/lib/typescript/src/useNavigationState.d.ts.map +1 -1
  102. package/lib/typescript/src/useOnAction.d.ts.map +1 -1
  103. package/lib/typescript/src/useOnPreventRemove.d.ts +2 -6
  104. package/lib/typescript/src/useOnPreventRemove.d.ts.map +1 -1
  105. package/lib/typescript/src/useOptionsGetters.d.ts.map +1 -1
  106. package/lib/typescript/src/usePreventRemove.d.ts.map +1 -1
  107. package/lib/typescript/src/usePreventRemoveContext.d.ts +1 -0
  108. package/lib/typescript/src/usePreventRemoveContext.d.ts.map +1 -1
  109. package/lib/typescript/src/useRoute.d.ts +1 -1
  110. package/lib/typescript/src/useRoute.d.ts.map +1 -1
  111. package/lib/typescript/src/useRouteCache.d.ts.map +1 -1
  112. package/lib/typescript/src/useScheduleUpdate.d.ts +5 -4
  113. package/lib/typescript/src/useScheduleUpdate.d.ts.map +1 -1
  114. package/lib/typescript/src/useSyncState.d.ts.map +1 -1
  115. package/lib/typescript/src/utilities.d.ts +21 -38
  116. package/lib/typescript/src/utilities.d.ts.map +1 -1
  117. package/lib/typescript/src/validatePathConfig.d.ts.map +1 -1
  118. package/package.json +6 -8
  119. package/src/BaseNavigationContainer.tsx +9 -2
  120. package/src/DataLoading.tsx +139 -0
  121. package/src/NavigationBuilderContext.tsx +5 -1
  122. package/src/NavigationIndependentTree.tsx +11 -11
  123. package/src/NavigationProvider.tsx +13 -16
  124. package/src/PreventRemoveContext.tsx +1 -0
  125. package/src/PreventRemoveProvider.tsx +48 -43
  126. package/src/StaticNavigation.tsx +164 -99
  127. package/src/StaticTreeContext.tsx +7 -0
  128. package/src/checkSerializable.tsx +20 -14
  129. package/src/createNavigationContainerRef.tsx +12 -9
  130. package/src/createNavigatorFactory.tsx +27 -18
  131. package/src/getActionFromState.tsx +18 -16
  132. package/src/getPathFromState.tsx +167 -132
  133. package/src/getPatternParts.tsx +2 -2
  134. package/src/getStateFromPath.tsx +260 -193
  135. package/src/index.tsx +3 -0
  136. package/src/types.tsx +298 -62
  137. package/src/useEventEmitter.tsx +7 -2
  138. package/src/useKeyedChildListeners.tsx +4 -2
  139. package/src/useNavigation.tsx +2 -21
  140. package/src/useNavigationBuilder.tsx +7 -24
  141. package/src/useNavigationCache.tsx +26 -19
  142. package/src/useNavigationHelpers.tsx +26 -9
  143. package/src/useNavigationState.tsx +90 -60
  144. package/src/useOnAction.tsx +55 -3
  145. package/src/useOnPreventRemove.tsx +68 -36
  146. package/src/useOptionsGetters.tsx +4 -1
  147. package/src/usePreventRemove.tsx +11 -2
  148. package/src/useRoute.tsx +3 -5
  149. package/src/useRouteCache.tsx +19 -11
  150. package/src/useScheduleUpdate.tsx +8 -7
  151. package/src/useSyncState.tsx +5 -1
  152. package/src/utilities.tsx +36 -41
  153. package/src/validatePathConfig.tsx +86 -58
@@ -1,4 +1,8 @@
1
- import type { NavigationState, ParamListBase } from '@react-navigation/routers';
1
+ import type {
2
+ NavigationState,
3
+ ParamListBase,
4
+ Route,
5
+ } from '@react-navigation/routers';
2
6
  import * as React from 'react';
3
7
  import { isValidElementType } from 'react-is';
4
8
 
@@ -7,10 +11,11 @@ import {
7
11
  getPatternParts,
8
12
  type PatternPart,
9
13
  } from './getPatternParts';
14
+ import { StaticTreeContext } from './StaticTreeContext';
10
15
  import type {
11
- DefaultNavigatorOptions,
12
16
  EventMapBase,
13
17
  NavigationListBase,
18
+ NavigatorProps,
14
19
  NavigatorScreenParams,
15
20
  NavigatorTypeBagBase,
16
21
  NavigatorTypeBagFor,
@@ -27,6 +32,8 @@ import type {
27
32
  HasArguments,
28
33
  InferParamsFromLinking,
29
34
  KeysOf,
35
+ NoExcessObject,
36
+ NotUndefinedObject,
30
37
  StandardSchemaV1,
31
38
  UnionToIntersection,
32
39
  ValidPathPattern,
@@ -81,14 +88,15 @@ type ParamsForScreen<T> = [T] extends [{ config: any }]
81
88
  type ParamsForScreenEntry<T> = T extends T ? ParamsForScreen<T> : never;
82
89
 
83
90
  // Only infer params from linking if it's a pattern (i.e., contains ':')
84
- // or if parse is present for query params.
91
+ // or if parse is present, which can also define query params.
85
92
  // This avoids inferring non-literals like 'string' without parse.
86
- type ShouldInferFromLinking<Linking> = Linking extends
87
- | ValidPathPattern
88
- | { path: ValidPathPattern }
89
- | { parse: Record<string, unknown> }
93
+ type ShouldInferFromLinking<Linking> = Linking extends {
94
+ parse: Record<string, unknown>;
95
+ }
90
96
  ? true
91
- : false;
97
+ : Linking extends ValidPathPattern | { path: ValidPathPattern }
98
+ ? true
99
+ : false;
92
100
 
93
101
  /**
94
102
  * Params type derived from both linking and screen.
@@ -104,7 +112,13 @@ type ShouldInferFromLinking<Linking> = Linking extends
104
112
  type ParamsForConfig<Linking, Screen, Params = ParamsForScreen<Screen>> =
105
113
  ShouldInferFromLinking<Linking> extends true
106
114
  ? [Screen] extends [{ config: any }]
107
- ? FlatType<InferParamsFromLinking<Linking>> & Params
115
+ ? undefined extends Params
116
+ ? FlatType<InferParamsFromLinking<Linking>> & Params
117
+ : // Optional linking params make the whole route params type optional when intersected.
118
+ // e.g. `({...} | undefined) & NavigatorScreenParams<{...}>` adds `| undefined` to the whole type.
119
+ // But if nested navigator had required params, it should still be required.
120
+ // So we remove `| undefined` from linking params before intersecting with nested navigator params.
121
+ FlatType<NotUndefinedObject<InferParamsFromLinking<Linking>>> & Params
108
122
  : undefined extends Params
109
123
  ? FlatType<InferParamsFromLinking<Linking>>
110
124
  : FlatType<InferParamsFromLinking<Linking> & Params>
@@ -124,15 +138,7 @@ type ParamListForScreens<Screens> = {
124
138
  : ParamsForScreenEntry<Screens[Key]>;
125
139
  };
126
140
 
127
- type ParamListForGroups<
128
- Groups extends
129
- | Readonly<{
130
- [key: string]: {
131
- screens: {};
132
- };
133
- }>
134
- | undefined,
135
- > = Groups extends {
141
+ type ParamListForGroups<Groups> = Groups extends {
136
142
  [key: string]: {
137
143
  screens: infer Screens;
138
144
  };
@@ -140,27 +146,20 @@ type ParamListForGroups<
140
146
  ? ParamListForScreens<UnionToIntersection<Screens>>
141
147
  : {};
142
148
 
143
- type RouteTypeBase = {
144
- key: string;
145
- name: string;
146
- path?: string | undefined;
147
- history?: { type: 'params'; params: object }[] | undefined;
148
- };
149
-
150
- type RouteType<Params, P = AnyToUnknown<Params>> = Readonly<
151
- RouteTypeBase &
149
+ type StaticRoute<Params, P = AnyToUnknown<Params>> = Readonly<
150
+ Omit<Route<string>, 'params'> &
152
151
  (undefined extends Params
153
152
  ? {
154
153
  /**
155
154
  * Params for this route
156
155
  */
157
- params?: P;
156
+ params?: P extends object ? Readonly<P> : P;
158
157
  }
159
158
  : {
160
159
  /**
161
160
  * Params for this route
162
161
  */
163
- params: P;
162
+ params: Readonly<P>;
164
163
  })
165
164
  >;
166
165
 
@@ -221,23 +220,25 @@ type StaticScreenConfigLinkingAlias = {
221
220
  shared?: boolean;
222
221
  };
223
222
 
223
+ type StaticScreenConfigLinkingExtras = {
224
+ /**
225
+ * Additional path alias that will be matched to the same screen.
226
+ */
227
+ alias?: (string | StaticScreenConfigLinkingAlias)[];
228
+ /**
229
+ * Name of the initial route to use for the nested navigator when the path matches.
230
+ */
231
+ initialRouteName?: string | undefined;
232
+ /**
233
+ * Path configuration for child screens in the nested navigator.
234
+ * Only supported when the screen renders a navigator with dynamic API.
235
+ */
236
+ screens?: PathConfigMap<ParamListBase> | undefined;
237
+ };
238
+
224
239
  export type StaticScreenConfigLinking =
225
240
  | string
226
- | (StaticScreenConfigLinkingAlias & {
227
- /**
228
- * Additional path alias that will be matched to the same screen.
229
- */
230
- alias?: (string | StaticScreenConfigLinkingAlias)[];
231
- /**
232
- * Name of the initial route to use for the nested navigator when the path matches.
233
- */
234
- initialRouteName?: string | undefined;
235
- /**
236
- * Path configuration for child screens in the nested navigator.
237
- * Only supported when the screen renders a navigator with dynamic API.
238
- */
239
- screens?: PathConfigMap<ParamListBase> | undefined;
240
- })
241
+ | (StaticScreenConfigLinkingAlias & StaticScreenConfigLinkingExtras)
241
242
  | null
242
243
  | undefined;
243
244
 
@@ -287,7 +288,7 @@ export type StaticScreenConfig<
287
288
  options?:
288
289
  | ScreenOptions
289
290
  | ((props: {
290
- route: RouteType<Params>;
291
+ route: StaticRoute<Params>;
291
292
  navigation: Navigation;
292
293
  theme: Theme;
293
294
  }) => ScreenOptions);
@@ -307,7 +308,7 @@ export type StaticScreenConfig<
307
308
  listeners?:
308
309
  | ScreenListeners<State, EventMap>
309
310
  | ((props: {
310
- route: RouteType<Params>;
311
+ route: StaticRoute<Params>;
311
312
  navigation: Navigation;
312
313
  }) => ScreenListeners<State, EventMap>);
313
314
 
@@ -327,7 +328,7 @@ export type StaticScreenConfig<
327
328
  *
328
329
  */
329
330
  layout?: (props: {
330
- route: RouteType<Params>;
331
+ route: StaticRoute<Params>;
331
332
  options: ScreenOptions;
332
333
  navigation: Navigation;
333
334
  theme: Theme;
@@ -354,7 +355,9 @@ export type StaticScreenConfig<
354
355
  * getId: ({ params }) => params?.userId,
355
356
  * ```
356
357
  */
357
- getId?: (props: { params: AnyToUnknown<Params> }) => string | undefined;
358
+ getId?: (props: {
359
+ params: AnyToUnknown<Params extends object ? Readonly<Params> : Params>;
360
+ }) => string | undefined;
358
361
 
359
362
  /**
360
363
  * Linking config for the screen.
@@ -376,11 +379,27 @@ export type StaticScreenConfig<
376
379
  * Optional key for this screen.
377
380
  */
378
381
  navigationKey?: string;
382
+
383
+ /**
384
+ * Loader function to start loading data when the screen is navigated to.
385
+ *
386
+ * @example
387
+ * ```js
388
+ * UNSTABLE_loader: ({ params }) => loadProfile(params.id),
389
+ * ```
390
+ */
391
+ UNSTABLE_loader?: (options: {
392
+ name: string;
393
+ params: AnyToUnknown<Params>;
394
+ }) => Promise<void>;
379
395
  };
380
396
 
381
397
  export type StaticScreenFactory<in out Bag extends NavigatorTypeBagBase> = <
382
398
  const Linking extends StaticScreenConfigLinking,
383
399
  const Screen extends StaticScreenConfigScreen,
400
+ const ProvidedOptions extends
401
+ | Bag['ScreenOptions']
402
+ | ((...args: never[]) => unknown) = Bag['ScreenOptions'],
384
403
  >(
385
404
  config: StaticScreenConfig<
386
405
  Linking,
@@ -389,7 +408,10 @@ export type StaticScreenFactory<in out Bag extends NavigatorTypeBagBase> = <
389
408
  Bag['ScreenOptions'],
390
409
  Bag['EventMap'],
391
410
  Bag['NavigationList'][keyof Bag['ParamList']]
392
- >
411
+ > & {
412
+ options?: ProvidedOptions &
413
+ NoExcessOptions<ProvidedOptions, Bag['ScreenOptions']>;
414
+ }
393
415
  ) => StaticScreenConfig<
394
416
  Linking,
395
417
  Screen,
@@ -455,51 +477,33 @@ type StaticConfigGroup<
455
477
  >;
456
478
  };
457
479
 
458
- export type StaticConfig<Bag extends NavigatorTypeBagBase> =
459
- StaticConfigInternal<
480
+ export type StaticConfig<
481
+ Bag extends NavigatorTypeBagBase,
482
+ Screens = StaticConfigScreens<
460
483
  Bag['ParamList'],
461
484
  Bag['State'],
462
485
  Bag['ScreenOptions'],
463
486
  Bag['EventMap'],
464
- Bag['NavigationList'],
465
- Bag['Navigator']
466
- >;
467
-
468
- type StaticConfigInternal<
469
- ParamList extends ParamListBase,
470
- State extends NavigationState,
471
- ScreenOptions extends {},
472
- EventMap extends EventMapBase,
473
- NavigationList extends NavigationListBase<ParamList>,
474
- Navigator extends React.ComponentType<any>,
475
- Screens = StaticConfigScreens<
476
- ParamList,
477
- State,
478
- ScreenOptions,
479
- EventMap,
480
- NavigationList
487
+ Bag['NavigationList']
481
488
  >,
482
489
  Groups = {
483
490
  [key: string]: StaticConfigGroup<
484
- ParamList,
485
- State,
486
- ScreenOptions,
487
- EventMap,
488
- NavigationList
491
+ Bag['ParamList'],
492
+ Bag['State'],
493
+ Bag['ScreenOptions'],
494
+ Bag['EventMap'],
495
+ Bag['NavigationList']
489
496
  >;
490
497
  },
491
498
  > = Omit<
492
- Omit<
493
- React.ComponentProps<Navigator>,
494
- keyof DefaultNavigatorOptions<any, any, any, any, any>
495
- > &
496
- DefaultNavigatorOptions<
497
- ParamList,
498
- State,
499
- ScreenOptions,
500
- EventMap,
501
- NavigationList[keyof ParamList]
502
- >,
499
+ NavigatorProps<
500
+ Bag['ParamList'],
501
+ Bag['State'],
502
+ Bag['ScreenOptions'],
503
+ Bag['EventMap'],
504
+ Bag['NavigationList'][keyof Bag['ParamList']],
505
+ Bag['Navigator']
506
+ >,
503
507
  'screens' | 'children'
504
508
  > &
505
509
  (
@@ -525,6 +529,67 @@ type StaticConfigInternal<
525
529
  }
526
530
  );
527
531
 
532
+ type NoExcessOptions<Provided, Allowed extends {}> = Provided extends (
533
+ ...args: never[]
534
+ ) => infer Return
535
+ ? (...args: never[]) => Allowed & NoExcessObject<Return, Allowed>
536
+ : NoExcessObject<Provided, Allowed>;
537
+
538
+ type NoExcessScreen<Screen, ScreenOptions extends {}> = Screen extends {
539
+ screen: unknown;
540
+ options: unknown;
541
+ }
542
+ ? { options: NoExcessOptions<Screen['options'], ScreenOptions> }
543
+ : unknown;
544
+
545
+ type NoExcessScreens<Screens, ScreenOptions extends {}> = {
546
+ [RouteName in keyof Screens]: NoExcessScreen<
547
+ Screens[RouteName],
548
+ ScreenOptions
549
+ >;
550
+ };
551
+
552
+ type NoExcessGroups<
553
+ Groups,
554
+ Bag extends NavigatorTypeBagBase,
555
+ ScreenOptions extends {},
556
+ > = {
557
+ [GroupName in keyof Groups]: NoExcessObject<
558
+ Groups[GroupName],
559
+ StaticConfigGroup<
560
+ ParamListBase,
561
+ NavigationState,
562
+ {},
563
+ EventMapBase,
564
+ NavigationListBase<ParamListBase>
565
+ >
566
+ > &
567
+ NoExcessStaticConfig<Groups[GroupName], Bag, ScreenOptions>;
568
+ };
569
+
570
+ // Each property is probed with `Config extends { key: infer X }` and the results are intersected.
571
+ // These conditionals stay deferred while the config is inferred, so they don't interfere with the inference.
572
+ // Indexed access (`Config['screens']`) or a mapped type over the whole config breaks the param list inference.
573
+ export type NoExcessStaticConfig<
574
+ Config,
575
+ Bag extends NavigatorTypeBagBase,
576
+ ScreenOptions extends {} = Bag['ScreenOptions'],
577
+ > = (Config extends { screenOptions: infer ProvidedOptions }
578
+ ? {
579
+ screenOptions: NoExcessOptions<ProvidedOptions, ScreenOptions>;
580
+ }
581
+ : unknown) &
582
+ (Config extends { screens: infer Screens }
583
+ ? {
584
+ screens: NoExcessScreens<Screens, ScreenOptions>;
585
+ }
586
+ : unknown) &
587
+ (Config extends { groups: infer Groups }
588
+ ? {
589
+ groups: NoExcessGroups<Groups, Bag, ScreenOptions>;
590
+ }
591
+ : unknown);
592
+
528
593
  /**
529
594
  * Props for a screen component which is rendered by a static navigator.
530
595
  * Takes the route params as a generic argument.
@@ -533,7 +598,7 @@ export type StaticScreenProps<
533
598
  in out T extends Record<string, unknown> | undefined,
534
599
  > = {
535
600
  route: {
536
- params: T;
601
+ readonly params: T;
537
602
  };
538
603
  };
539
604
 
@@ -723,14 +788,16 @@ export function createComponentForStaticConfig<
723
788
  : { ...rest.screenListeners, ...props.screenListeners };
724
789
 
725
790
  return (
726
- <Navigator
727
- {...rest}
728
- {...props}
729
- screenOptions={screenOptions}
730
- screenListeners={screenListeners}
731
- >
732
- {children}
733
- </Navigator>
791
+ <StaticTreeContext.Provider value={tree}>
792
+ <Navigator
793
+ {...rest}
794
+ {...props}
795
+ screenOptions={screenOptions}
796
+ screenListeners={screenListeners}
797
+ >
798
+ {children}
799
+ </Navigator>
800
+ </StaticTreeContext.Provider>
734
801
  );
735
802
  };
736
803
 
@@ -739,7 +806,7 @@ export function createComponentForStaticConfig<
739
806
  return NavigatorComponent;
740
807
  }
741
808
 
742
- type TreeForPathConfig = {
809
+ export type TreeForPathConfig = {
743
810
  config: ConfigForPathConfig;
744
811
  };
745
812
 
@@ -751,11 +818,7 @@ type ConfigForPathConfig = {
751
818
 
752
819
  type LinkingForPathConfig =
753
820
  | string
754
- | (Partial<StaticScreenConfigLinkingAlias> & {
755
- alias?: (string | StaticScreenConfigLinkingAlias)[];
756
- initialRouteName?: string | undefined;
757
- screens?: PathConfigMap<ParamListBase> | undefined;
758
- })
821
+ | (Partial<StaticScreenConfigLinkingAlias> & StaticScreenConfigLinkingExtras)
759
822
  | null
760
823
  | undefined;
761
824
 
@@ -765,7 +828,9 @@ type ScreenForPathConfig =
765
828
  | ScreenValueForPathConfig
766
829
  | {
767
830
  screen: ScreenValueForPathConfig;
831
+ initialParams?: object;
768
832
  linking?: LinkingForPathConfig;
833
+ UNSTABLE_loader?: unknown;
769
834
  };
770
835
 
771
836
  type PathConfigMapForStaticNavigation = Record<
@@ -0,0 +1,7 @@
1
+ import * as React from 'react';
2
+
3
+ import type { TreeForPathConfig } from './StaticNavigation';
4
+
5
+ export const StaticTreeContext = React.createContext<
6
+ TreeForPathConfig | undefined
7
+ >(undefined);
@@ -1,16 +1,18 @@
1
- type Result =
2
- | { serializable: true }
3
- | {
4
- serializable: false;
5
- location: (string | number)[];
6
- reason: string;
7
- };
1
+ type Success = { serializable: true };
2
+
3
+ type Failure = {
4
+ serializable: false;
5
+ location: (string | number)[];
6
+ reason: string;
7
+ };
8
+
9
+ type Result = Success | Failure;
8
10
 
9
11
  const checkSerializableWithoutCircularReference = (
10
12
  o: { [key: string]: any },
11
13
  seen: Set<any>,
12
14
  location: (string | number)[]
13
- ): Result => {
15
+ ): Failure | undefined => {
14
16
  if (
15
17
  o === undefined ||
16
18
  o === null ||
@@ -18,7 +20,7 @@ const checkSerializableWithoutCircularReference = (
18
20
  typeof o === 'number' ||
19
21
  typeof o === 'string'
20
22
  ) {
21
- return { serializable: true };
23
+ return undefined;
22
24
  }
23
25
 
24
26
  if (
@@ -52,7 +54,7 @@ const checkSerializableWithoutCircularReference = (
52
54
  );
53
55
  location.pop();
54
56
 
55
- if (!childResult.serializable) {
57
+ if (childResult) {
56
58
  seen.delete(o);
57
59
  return childResult;
58
60
  }
@@ -67,7 +69,7 @@ const checkSerializableWithoutCircularReference = (
67
69
  );
68
70
  location.pop();
69
71
 
70
- if (!childResult.serializable) {
72
+ if (childResult) {
71
73
  seen.delete(o);
72
74
  return childResult;
73
75
  }
@@ -76,9 +78,13 @@ const checkSerializableWithoutCircularReference = (
76
78
 
77
79
  seen.delete(o);
78
80
 
79
- return { serializable: true };
81
+ return undefined;
80
82
  };
81
83
 
82
- export function checkSerializable(o: { [key: string]: any }) {
83
- return checkSerializableWithoutCircularReference(o, new Set<any>(), []);
84
+ export function checkSerializable(o: { [key: string]: any }): Result {
85
+ return (
86
+ checkSerializableWithoutCircularReference(o, new Set<any>(), []) ?? {
87
+ serializable: true,
88
+ }
89
+ );
84
90
  }
@@ -30,6 +30,8 @@ export function createNavigationContainerRef<
30
30
 
31
31
  const listeners: Record<string, ((...args: any[]) => void)[]> = {};
32
32
 
33
+ let current: NavigationContainerRef<ParamList> | null = null;
34
+
33
35
  const removeListener = (
34
36
  event: string,
35
37
  callback: (...args: any[]) => void
@@ -37,9 +39,12 @@ export function createNavigationContainerRef<
37
39
  if (listeners[event]) {
38
40
  listeners[event] = listeners[event].filter((cb) => cb !== callback);
39
41
  }
40
- };
41
42
 
42
- let current: NavigationContainerRef<ParamList> | null = null;
43
+ current?.removeListener(
44
+ event as keyof NavigationContainerEventMap,
45
+ callback
46
+ );
47
+ };
43
48
 
44
49
  const ref: NavigationContainerRefWithCurrent<ParamList> = {
45
50
  get current() {
@@ -68,7 +73,11 @@ export function createNavigationContainerRef<
68
73
  },
69
74
  ...methods.reduce<any>((acc, name) => {
70
75
  acc[name] = (...args: any[]) => {
71
- if (current == null) {
76
+ if (name === 'removeListener') {
77
+ const [event, callback] = args;
78
+
79
+ removeListener(event, callback);
80
+ } else if (current == null) {
72
81
  switch (name) {
73
82
  case 'addListener': {
74
83
  const [event, callback] = args;
@@ -78,12 +87,6 @@ export function createNavigationContainerRef<
78
87
 
79
88
  return () => removeListener(event, callback);
80
89
  }
81
- case 'removeListener': {
82
- const [event, callback] = args;
83
-
84
- removeListener(event, callback);
85
- break;
86
- }
87
90
  default:
88
91
  console.error(NOT_INITIALIZED_ERROR);
89
92
  }
@@ -5,39 +5,48 @@ import { Group } from './Group';
5
5
  import { Screen } from './Screen';
6
6
  import {
7
7
  createComponentForStaticConfig,
8
+ type NoExcessStaticConfig,
8
9
  type StaticConfig,
9
10
  type StaticParamList,
10
11
  } from './StaticNavigation';
11
12
  import type {
12
13
  NavigatorTypeBagBase,
13
14
  NavigatorTypeBagFor,
15
+ NestedNavigatorsForParamList,
14
16
  TypedNavigator,
15
17
  } from './types';
16
- import type { KeysOf } from './utilities';
18
+ import type { KeysOf, NoExcessObject } from './utilities';
19
+
20
+ type NavigatorNesting<ParamList extends ParamListBase, Nesting> = {
21
+ [RouteName in keyof ParamList]?: unknown;
22
+ } & Record<Exclude<KeysOf<Nesting>, keyof ParamList>, never>;
23
+
24
+ type ValidNavigatorNesting<ParamList extends ParamListBase, Nesting> =
25
+ Nesting extends NavigatorNesting<ParamList, Nesting> ? Nesting : never;
26
+
27
+ type AnyStaticConfig<TypeBag extends NavigatorTypeBagBase> = StaticConfig<
28
+ NavigatorTypeBagFor<TypeBag, ParamListBase>
29
+ >;
17
30
 
18
31
  export type TypedNavigatorFactory<in out TypeBag extends NavigatorTypeBagBase> =
19
32
  {
20
- <const ParamList extends ParamListBase>(): TypedNavigator<
33
+ <
34
+ const ParamList extends ParamListBase,
35
+ const Nesting extends NavigatorNesting<ParamList, Nesting> =
36
+ ValidNavigatorNesting<
37
+ ParamList,
38
+ NestedNavigatorsForParamList<ParamList>
39
+ >,
40
+ >(): TypedNavigator<
21
41
  NavigatorTypeBagFor<TypeBag, ParamList>,
22
- undefined
42
+ undefined,
43
+ Nesting
23
44
  >;
24
45
  <
25
- const Config extends StaticConfig<
26
- NavigatorTypeBagFor<TypeBag, ParamListBase>
27
- > &
28
- // TS only checks for excess properties for non-generic object literal types.
29
- // Since `Config` is generic, extra keys satisfy the constraint and slip through.
30
- // So we force any key in `Config` that isn't a known key to have the type `never`,
31
- // Thus causing an error for any extra key.
32
- Record<
33
- Exclude<
34
- keyof Config,
35
- KeysOf<StaticConfig<NavigatorTypeBagFor<TypeBag, ParamListBase>>>
36
- >,
37
- never
38
- >,
46
+ const Config extends AnyStaticConfig<TypeBag> &
47
+ NoExcessObject<Config, AnyStaticConfig<TypeBag>>,
39
48
  >(
40
- config: Config
49
+ config: Config & NoExcessStaticConfig<NoInfer<Config>, TypeBag>
41
50
  ): TypedNavigator<
42
51
  NavigatorTypeBagFor<TypeBag, StaticParamList<{ config: Config }>>,
43
52
  Config