I was following the documentation tutorial about using typescript with react-navigation when I encountered some problems.
I have a Tab navigator that consists of Stack navigators, each of which contains its respective screens:
export type HomeStackParamList = {
Home: undefined;
Workout: undefined;
Settings: undefined;
};
export type ExecisesStackParamList = {
Debug: { exercises: PredefinedExercise[] } | undefined;
Exercises: { mode: 'select' | 'view' };
Settings: undefined;
};
export type AppTabParamList = {
HomeTab: NavigatorScreenParams<HomeStackParamList>;
ExercisesTab: NavigatorScreenParams<ExecisesStackParamList>;
};
// utility for combining props
export type ExercisesTabScreenProps<ScreenName extends keyof ExecisesStackParamList> =
CompositeScreenProps<
NativeStackScreenProps<ExecisesStackParamList, ScreenName>,
BottomTabScreenProps<AppTabParamList, 'ExercisesTab'>
>;
When my screen component uses props combined with CompositeScreenProps everything seems fine - as documentation says navigation object have methods from Tab as well as from Stack navigator, and route object has correct params typings.
export default function ExercisesScreen(props: ExercisesTabScreenProps<'Exercises'>) {
const { navigation, route } = props; // OK
// ...
}
Problem starts when I need to navigate to another screen. Despite correct hints:

when I pass route of parent navigator (e.g. ExerciseTab or HomeTab) I get not assignable error:
const handleSelectConfirm = () => {
navigation.navigate('ExercisesTab');
};
/* Results with:
Argument of type 'string' is not assignable to parameter of type '{ name: "ExercisesTab";
params: NavigatorScreenParams<ExecisesStackParamList>; path?: string | undefined; merge?:
boolean | undefined; } | { ...; } | { ...; } | { ...; } | { ...; }'.
*/
But when I use route from nested navigator, I get no errors:
const handleSelectConfirm = () => {
navigation.navigate('Settings');
};
// OK
Any ideas why is this happening?