skip to Main Content

I am working with expo and React Native, trying to push props to other screens using navigation. The code compiles and pushes the props, but I get this error when passing the props as a second argument to the navigation.navigate() function:

Argument of type ‘[never, { email: string; password: string; }]’ is not assignable to parameter of type ‘never’.

I also get this error when trying to navigate to a screen without passing props:

Argument of type ‘string’ is not assignable to parameter of type ‘{ key: string; params?: undefined; merge?: boolean | undefined; } | { name: "SignUp"; key?: string | undefined; params: undefined; merge?: boolean | undefined; } | { key: string; params?: { email: string; password: string; } | undefined; merge?: boolean | undefined; } | … 10 more … | { …; }’.ts(2345)

It goes away when I add ‘as never’.

This is where I call the function in my SignUp.tsx screen:

import { RootStackParamList } from "../../App";
import { NativeStackScreenProps } from "@react-navigation/native-stack";
type propsType = NativeStackScreenProps<RootStackParamList, 'SignUp'>;

const SignUp = (props: propsType) => {
    const {navigation} = props;

.......

            return(
               ...
                <MainButton 
                canGoBack 
                style={tw`h-20 justify-center mt-3 mx-auto`} 
                text={"Sign up"} 
                targetPage="Characteristics" 
                onPress={() => navigation.navigate("Characteristics" )} 
                navigationData={{ email: formInput.email, password: formInput.password }} />)

This is the App.tsx where I have the RootStackParamList type and also the Stack Navigator:

export type RootStackParamList = {
    Login: undefined;
    SignUp: undefined;
    ProfileSetup: undefined;
    ProfileSetupDetails: undefined;
    IdealMatch: undefined;
    Characteristics: {
        email: string,
        password: string;
    };
    Profile: undefined;
};

const Stack = createNativeStackNavigator<RootStackParamList>();

export type Props = NativeStackScreenProps<RootStackParamList, 'Characteristics'>;



const App: React.FC<RootStackParamList> = () => {
    return (
      <NavigationContainer>
          <Stack.Navigator>
              <Stack.Screen name="Login" component={Login}
                             options={{ headerShown: false }}/>
              <Stack.Screen name="SignUp" component={SignUp}
                             options={{ headerShown: false }}/>
              <Stack.Screen name="ProfileSetup" component={ProfileSetup}
                             options={{ headerShown: false }}/>
              <Stack.Screen name="ProfileSetupDetails" component={ProfileSetupDetails}
                             options={{ headerShown: false }}/>
              <Stack.Screen name="IdealMatch" component={IdealMatch}
                             options={{ headerShown: false }}/>
              <Stack.Screen name="Characteristics" component={Characteristics}
                             options={{ headerShown: false }}
                             />
              <Stack.Screen name="Profile" component={Profile}
                             options={{ headerShown: false }}/>
          </Stack.Navigator>
      </NavigationContainer>
    );
}

I need suggestions. I am relatively new to React Native and react navigation.

Creating a route const with the path name and the data I’m pushing and passing it to the navigate seemed to fix it, but I don’t know if its ok to leave it like this:

const route = ["Characteristics", { email: formInput.email, password: formInput: password}];
navigation.navigate(...(route as never));

2

Answers


  1. Chosen as BEST ANSWER

    Fixed it by creating a navigation constant and removing the props: propsType arg from my SignUp screen:

    const navigation = useNavigation<StackNavigationProp<RootStackParamList>>();
    

    I still wonder if i have to create a new navigation constant on each screen of the stack?


  2. I don’t know the react-navigation package in particular, but regarding your as never cast, the issue is that your route is an array of the union type (string | params)[], rather than the tuple type [string, params]. When you spread an array into navigate, it won’t accept anything but a string in the first parameter, but spreading your current route tells it that it might receive either a string or typeof params.

    Rather than this:

    const route = ["Characteristics", { email: "", password: ""}];
    

    Add as const to your definition, which tells Typescript "this is a tuple type":

    const routeTuple = ["Characteristics", { email: "", password: ""}] as const;
    

    See this playground link for a demonstration of the difference.

    The as never cast tells Typescript to ignore any inferred type data, and to just treat the given variable as never. It punches a hole in the typechecking, and should be done only very rarely, and when you specifically know that type overrides are appropriate.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search