React Stack Navigation TypeScript - Cannot reset using route from parent

30 views Asked by At

I have a typed, nested stack navigator and am trying to reset the navigation from a screen to another which is on the parent. TypeScript is refusing to accept it as a valid name to reset, only screens in the child are available. However, for navigate, all screens are available as expected.

For example, this is ok:

navigation.navigate("Welcome");

and

navigation.navigate("MainStack");

But while this is ok:

navigation.reset({
    index: 0,
    routes: [{ name: "Welcome" }],
  });

The following gives the TypeScript error Type '"MainStack"' is not assignable to type 'keyof IntroductionStackParamList'.ts

navigation.reset({
    index: 0,
    routes: [{ name: "MainStack" }],
  });

Type definition:

type PreloadingScreenNavigationProp = CompositeScreenProps<
  NativeStackScreenProps<IntroductionStackParamList, "Preloading">,
  NativeStackScreenProps<AppStackParamList>
>;

Can anyone shed a clue on what I am doing wrong please?

Full navigation structure:

const AppStack = createNativeStackNavigator<AppStackParamList>();
const IntroductionStack =
  createNativeStackNavigator<IntroductionStackParamList>();
const OnboardingStack = createNativeStackNavigator<OnboardingStackParamList>();
const LogsStack = createNativeStackNavigator<LogsStackParamList>();
const Tab = createBottomTabNavigator<TabParamList>();

export type AppStackParamList = {
  IntroductionStack: NavigatorScreenParams<IntroductionStackParamList>;
  OnboardingStack: NavigatorScreenParams<OnboardingStackParamList>;
  MainStack: NavigatorScreenParams<TabParamList>;
};

export type IntroductionStackParamList = {
  Preloading: undefined;
  Welcome: undefined;
};

export type OnboardingStackParamList = {
  GettingStarted: undefined;
  Name: undefined;
  Address: undefined;
  Licence: undefined;
  OnboardingComplete: undefined;
  OnboardingSkipped: undefined;
};

export type LogsStackParamList = {
  FlightLogs: undefined;
  AddFlight: undefined;
};

export type TabParamList = {
  Logbook: undefined;
  FlyingSummary: undefined;
  Profile: undefined;
};

const AppStackNavigator = () => {
  return (
    <NavigationContainer>
      <AppStack.Navigator screenOptions={{ headerShown: false }}>
        <AppStack.Screen
          name="IntroductionStack"
          component={IntroductionStackNavigator}
        />
        <AppStack.Screen
          name="OnboardingStack"
          component={OnboardingStackNavigator}
        />
        <AppStack.Screen name="MainStack" component={BottomTabNavigator} />
      </AppStack.Navigator>
    </NavigationContainer>
  );
};

const IntroductionStackNavigator = () => {
  return (
    <IntroductionStack.Navigator screenOptions={{ headerShown: false }}>
      <IntroductionStack.Screen name="Preloading" component={Preloading} />
      <IntroductionStack.Screen name="Welcome" component={Welcome} />
    </IntroductionStack.Navigator>
  );
};

const OnboardingStackNavigator = () => {
  return (
    <OnboardingStack.Navigator screenOptions={{ headerShown: false }}>
      <OnboardingStack.Screen
        name="GettingStarted"
        component={GettingStarted}
      />
      <OnboardingStack.Screen name="Name" component={EnterName} />
      <OnboardingStack.Screen name="Address" component={EnterAddress} />
      <OnboardingStack.Screen name="Licence" component={SelectLicence} />
      <OnboardingStack.Screen
        name="OnboardingComplete"
        component={OnboardingComplete}
      />
      <OnboardingStack.Screen
        name="OnboardingSkipped"
        component={OnboardingSkipped}
      />
    </OnboardingStack.Navigator>
  );
};

const LogsStackNavigator = () => {
  return (
    <LogsStack.Navigator screenOptions={{ headerShown: false }}>
      <LogsStack.Screen name="FlightLogs" component={LogScreen} />
      <LogsStack.Screen name="AddFlight" component={AddLogScreen} />
    </LogsStack.Navigator>
  );
};

const BottomTabNavigator = () => {
  return (
    <Tab.Navigator
      screenOptions={{
        headerShown: true,
        tabBarItemStyle: { marginBottom: 5 },
      }}
    >
      <Tab.Screen
        name="Logbook"
        component={LogsStackNavigator}
        options={{
          tabBarIcon: () => <Icon size={20} source="view-list-outline" />,
        }}
      />
      <Tab.Screen
        name="FlyingSummary"
        component={FlyingSummaryScreen}
        options={{
          tabBarIcon: () => (
            <Icon size={20} source="calculator-variant-outline" />
          ),
        }}
      />
      <Tab.Screen
        name="Profile"
        component={PersonalInfoScreen}
        options={{
          tabBarIcon: () => <Icon size={20} source="account-circle-outline" />,
        }}
      />
    </Tab.Navigator>
  );
};

export default AppStackNavigator;
0

There are 0 answers