New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: remove NonNullable to fix recursive infer in PathConfigMap #11430
base: main
Are you sure you want to change the base?
fix: remove NonNullable to fix recursive infer in PathConfigMap #11430
Conversation
✅ Deploy Preview for react-navigation-example ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
I also fixed this for myself by removing |
Not working for me... |
Hi @johankasperi, Thanks for the PR! Can you please rebase and fix the CI? Also, can you add tests (use |
Hello 👋, this pull request has been open for more than a month with no activity on it. If you think this is still necessary with the latest version, please comment and ping a maintainer to get this reviewed, otherwise it will be closed automatically in 7 days. |
a30d94c
to
2a1e73e
Compare
@@ -76,7 +76,7 @@ export type RootDrawerParamList = { | |||
}; | |||
|
|||
export type RootStackParamList = ExampleScreensParamList & { | |||
Home: NavigatorScreenParams<RootDrawerParamList> | undefined; | |||
Home: NavigatorScreenParams<RootDrawerParamList>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you change this? Please revert to how it was
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please help me with how linking options should be defined here if the Home
route is NavigationScreenParams<RootDrawerParamList> | undefined
. I'm getting this typecheck error when it can be undefined:
Object literal may only specify known properties, and 'screens' does not exist in type 'Omit<PathConfig<{}>, "initialRouteName" | "screens">'
on this row
react-navigation/example/src/index.tsx
Line 69 in d0abdee
screens: { |
I have no experience from using NavigatorScreenParams
in a union with undefined
and really no idea how it should be handled by the lib. Would really appreciate some guidance. Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are omitting screens
from the type if it's not extending NavigatorScreenParams
here: https://github.com/react-navigation/react-navigation/blob/d0abdee67f5db8cf39112af535846ffededfb21d/packages/core/src/types.tsx#L1012C37-L1012C46
Since this PR removes NonNullable
from that line (because NonNullable
broke recursive infer) I think that makes it impossible for a route to be union of NavigatorScreenParams
and undefined
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it makes it impossible to have undefined
then it'd be a breaking change. The change needs to support | undefined
to be merged
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, but if a route is defined as NavigatorScreenParams<{}> | undefined
should you be able to config linking options for the nested navigator as in the example?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It wouldn't make sense to support | undefined
if it only works with some of the things and not others.
2a1e73e
to
e1249ea
Compare
I checked the main branch of the lib and from my testing the original
Thank you! I added a test in |
HI @johankasperi , did you manage to effectively resolve #9897 with your fix ? I copy pasted your changes, and it did not fix anything. I think, as soon as you define your type like this (from the example) : export type ParamList = {
ScreenA: undefined
ScreenB: NavigatorScreenParams<ParamListInnerNavigator> & {
someparam?: number,
}
} Assuming export type PathConfigMap<ParamList = {}> = {
[RouteName in keyof ParamList]?: ParamList[RouteName] extends NavigatorScreenParams<
infer T
>
? string | PathConfig<T>
: string | Omit<PathConfig<{}>, 'screens' | 'initialRouteName'>;
}; This check : ParamList[RouteName] extends NavigatorScreenParams<
infer T
>
? string | PathConfig<T>
: string | Omit<PathConfig<{}>, 'screens' | 'initialRouteName'>; resolves to false for export type NavigatorScreenParams<
ParamList,
State extends NavigationState = NavigationState,
OwnScreenParams extends {} = {},
> = OwnScreenParams &
(
| {
screen?: never;
params?: never;
initial?: never;
path?: string;
state: PartialState<State> | State | undefined;
}
| {
[RouteName in keyof ParamList]: undefined extends ParamList[RouteName]
? {
screen: RouteName;
params?: ParamList[RouteName];
initial?: boolean;
path?: string;
state?: never;
}
: {
screen: RouteName;
params: ParamList[RouteName];
initial?: boolean;
path?: string;
state?: never;
};
}[keyof ParamList]
); What do you think ? Thanks for your help ! |
Motivation
Fixes #10876 and #9897
Test plan
This change breaks typescript in the example app because the linking config does not match how all the navigators is setup. This wasn't catched before because of this bug in the
PathConfigMap
type. For example we are configuring a link to theChat
screen insideNativeStack
(with the path "native-stack/chat") but theChat
route isn't configured in theNativeStack
navigator: https://github.com/react-navigation/react-navigation/blob/main/example/src/Screens/NativeStack.tsx#L15I will happily fix this but wanted some feedback on the actual change to
PathConfigMap
first before putting in the hour(s) to fix the example project.Also I would like some feedback on how we would like to change the example project. Should all the routes "Article", "Albums", "Chat", "Contacts", "NewsFeed" and "Dialog" exist in every navigator? Or should just the linking config match how each individual navigator is setup? This would probably mean that we cannot reduce all SCREEN_NAMES to create the config because all navigators have different param lists.
I also have a fix for the 6.x branch: https://github.com/react-navigation/react-navigation/compare/6.x...johankasperi:react-navigation:fix-pathconfig-recursive-infer?expand=1