4

i am trying to refactor my code in react native from javascript to typescript with this tutorial: https://reactnavigation.org/docs/5.x/typescript/#nesting-navigators By doing types for react navigation v5 i got an error:

Property 'navigation' does not exist on type 'Omit<{ dispatch(action: Readonly<{ type: string; payload?: object; source?: string; target?: string; }> | ((state: TabNavigationState) => Readonly<...>)): void; ... 8 more ...; dangerouslyGetState(): TabNavigationState<...>; } & ... 10 more ... & StackActionHelpers<...>, "dispatch" | ... 11 more ...'.

My navigation structure: navigation structure

Expected results:

I want that i can access routes and params by Favorites Screen and can navigate to nested screen from there like this: (navigate("Root",{screen:"Something"})

Code works with javascript but by typescript there are errors with types.

My code:

types.ts

export type FavoriteProps = CompositeNavigationProp<
  MaterialTopTabNavigationProp<FavoritesParamList>,
  NativeStackNavigationProp<RootStackParamList>
>;

FavoriteScreen.tsx

const FavoriteScreen = ({ route, navigation }: FavoriteProps) => {
  const favoriteMovies = useAppSelector((state) => state.users.favoriteMovies);
  const favoriteSeries = useAppSelector((state) => state.users.favoriteSeries);

  const changeRouteName = () => {
    if (route.name === "favMovies") {
      return true;
    } else {
      return false;
    }
  };
  const [movieTab, setMovieTab] = useState(changeRouteName);

AppNavigator.tsx

export type RootStackParamList = {
  Home: undefined;
  ShowAll: { id: number; name: string };
...
};

const Stack = createNativeStackNavigator<RootStackParamList>();
function AppNavigator() {
        <Stack.Navigator>
          <Stack.Screen name="Home" component={TabScreens} options={{ headerShown: false }} />
    </Stack.Navigator>

export const TabScreens = ({ navigation }) => {
      <Tab.Screen name="Favorites" component={FavStackScreen} options={{ tabBarLabel: strings.favorites }} />
}
...

BottomTabNavigator.tsx

export type BottomTabParamList = {
...
  Favorites: NavigatorScreenParams<FavoritesParamList>;
  User: UserParamList;
};


export type FavoritesParamList = { favMovies: undefined; favSeries: undefined };

const Tab = createBottomTabNavigator<BottomTabParamList>();

const FavTab = createMaterialTopTabNavigator<FavoritesParamList>();
function FavStackScreen() {
  return (
    <FavTab.Navigator
      tabBarOptions={{
        indicatorStyle: { backgroundColor: "tomato" },
        labelStyle: { fontSize: 14, fontFamily: "Montserrat-Bold" },
      }}
    >
      <FavTab.Screen name="favMovies" component={FavoriteScreen} options={{ tabBarLabel: strings.movies }} />
      <FavTab.Screen name="favSeries" component={FavoriteScreen} options={{ tabBarLabel: strings.series }} />
    </FavTab.Navigator>
  );
}

Fixed by changing types to:

type FavoriteRouteProp = RouteProp<FavoritesParamList, "favMovies">;

type FavoriteNavigationProp = CompositeNavigationProp<
  MaterialTopTabNavigationProp<FavoritesParamList>,
  NativeStackNavigationProp<RootStackParamList>
>;

export type FavoriteProps = {
  navigation: FavoriteNavigationProp;
  route: FavoriteRouteProp;
};
mradex77
  • 118
  • 2
  • 8

2 Answers2

2

This defines the type for the navigation prop, not the whole props object

export type FavoriteProps = CompositeNavigationProp<
  MaterialTopTabNavigationProp<FavoritesParamList>,
  NativeStackNavigationProp<RootStackParamList>
>;

If you want to define type for the props, use:

export type FavoriteProps = CompositeScreenProps<
  MaterialTopTabScreenProps<FavoritesParamList>,
  NativeStackScreenProps<RootStackParamList>
>;

https://reactnavigation.org/docs/typescript

satya164
  • 9,464
  • 2
  • 31
  • 42
  • Thank you for your answer, im using react navigation v5, by this version there is nothing like CompositeScreenProps, but i was able to do something like this: type FavoriteRouteProp = RouteProp; type FavoriteNavigationProp = CompositeNavigationProp< MaterialTopTabNavigationProp, NativeStackNavigationProp >; export type FavoriteProps = { navigation: FavoriteNavigationProp; route: FavoriteRouteProp; }; – mradex77 Sep 03 '21 at 14:09
0

Fixed by changing types to:

type FavoriteRouteProp = RouteProp<FavoritesParamList, "favMovies">;

type FavoriteNavigationProp = CompositeNavigationProp<
  MaterialTopTabNavigationProp<FavoritesParamList>,
  NativeStackNavigationProp<RootStackParamList>
>;

export type FavoriteProps = {
  navigation: FavoriteNavigationProp;
  route: FavoriteRouteProp;
};
mradex77
  • 118
  • 2
  • 8