I'm trying to include React Navigation 6.x into a React Native project with Redux and therefore need to be able to access the navigator from outside components.
I'm following this guide (Navigating without the navigation prop) and have essentially the same code as in their example, which functionally works fine:
import { createNavigationContainerRef } from '@react-navigation/native';
export const navigationRef = createNavigationContainerRef()
export function navigate(name, params) {
if (navigationRef.isReady()) {
navigationRef.navigate(name, params);
}
}
However I'm also using Typescript.
React Navigation also have a guide on integrating Typescript (Type checking with TypeScript) which shows how to type the navigation ref itself, which works also fine:
export const navigationRef = createNavigationContainerRef<RootStackParamList>();
There is no example for typing the navigate
function though, and I haven't been able to get anything to work.
I thought the solution would be to copy the typing for the navigationRef.navigate()
method (defined here) and simply apply it to the wrapper function:
// navigationRef.navigate() typing...
//
// navigate<RouteName extends keyof ParamList>(
// ...args: undefined extends ParamList[RouteName]
// ? [screen: RouteName] | [screen: RouteName, params: ParamList[RouteName]]
// : [screen: RouteName, params: ParamList[RouteName]]
// ): void;
type ParamList = RootStackParamList;
type Navigate = <RouteName extends keyof ParamList>(
...args: undefined extends ParamList[RouteName]
? [screen: RouteName] | [screen: RouteName, params: ParamList[RouteName]]
: [screen: RouteName, params: ParamList[RouteName]]
) => void;
export const navigate: Navigate = (name, params) => {
if (navigationRef.isReady()) {
navigationRef.navigate(name, params);
}
}
// or...
export const navigate: typeof navigationRef.navigate = (name, params) => {
if (navigationRef.isReady()) {
navigationRef.navigate(name, params);
}
}
That unfortunately gives the following error:
Argument of type '[(undefined extends RootStackParamList[RouteName] ? [screen: RouteName] | [screen: RouteName, params: RootStackParamList[RouteName]] : [screen: ...])[0], (undefined extends RootStackParamList[RouteName] ? [screen: ...] | [screen: ...] : [screen: ...])[1]]' is not assignable to parameter of type 'undefined extends RootStackParamList[(undefined extends RootStackParamList[RouteName] ? [screen: RouteName] | [screen: RouteName, params: RootStackParamList[RouteName]] : [screen: ...])[0]] ? [screen: ...] | [screen: ...] : [screen: ...]'.ts(2345)