35

When I use useNavigation or from props { navigation } for navigate between screen using navigation.navigate('Home') the typescript return error Argument of type '"Main"' is not assignable to parameter of type '{ key: string; params?: undefined; merge?: boolean | undefined; } | { name: never; key?: string | undefined; params: never; merge?: boolean | undefined; }' what does it mean?

below is my code:

import React from 'react';
import { View } from 'react-native';
import { Button } from 'react-native-paper';
import { useNavigation } from '@react-navigation/native';

const Home: React.FC = () => {
  const navigation = useNavigation();

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Button onPress={() => navigation.navigate('Main')}>Navigate</Button>
    </View>
  );
};

export default React.memo(Home);

previously i used react navigation v5 and working find with that method

thanks for your help

3

7 Answers 7

47

Maybe you want to do something like this:

export type RootStackParamList = {
  Main: undefined;
  Home: undefined;
};

const Stack = createStackNavigator<RootStackParamList>();

export const RootNavigator = () => {
  return (
    <Stack.Navigator initialRouteName="Main">
      <Stack.Screen
        name="Main"
        component={Main}
      />
      <Stack.Screen
        name="Home"
        component={Home}
      />
    </Stack.Navigator>
  );
};

then in your code to do something like this:

type homeScreenProp = StackNavigationProp<RootStackParamList, 'Home'>;

const Home: React.FC = () => {
  const navigation = useNavigation<homeScreenProp>();

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Button onPress={() => navigation.navigate('Main')}>Navigate</Button>
    </View>
  );
};
Sign up to request clarification or add additional context in comments.

6 Comments

You should put some explanation as well. Makes it easier for others to understand the issue and solution
ok, maybe this article can help. benjaminwoojang.medium.com/…
I'm just do this but that is not working navigate function always return error message in Typescript, but not error in the application
Cannot find name 'RootStackParamList'. I got this error when i tried
@RahmanHaroon you need to import it from the first file. (It's exported here: export type RootStackParamList )
|
22

This is because you must specify this type, as this will ensure type-safety.

Solution:

1 - Type checking the navigator

// root.routes.tsx

import { createStackNavigator } from '@react-navigation/stack';

export type RootStackParamList = {
  Home: undefined;
  Profile: { userId: string };
  Feed: { sort: 'latest' | 'top' } | undefined;
};
const RootStack = createStackNavigator<RootStackParamList>();

2 - Specify a global type for your root navigator

// navigation.d.ts

import { RootStackParamList } from '../routes/root.routes';

declare global {
  namespace ReactNavigation {
    interface RootParamList extends RootStackParamList { }
  }
}

3 - Use it!

import { useNavigation } from '@react-navigation/native';

const navigation = useNavigation();

navigation.navigate('Home');

4- Extra! If you need to grab a parameter:

import { useRoute, RouteProp } from '@react-navigation/native';
import { RootStackParamList } from '../routes/root.routes';

const route = useRoute<RouteProp<RootStackParamList, 'Profile'>>();

const id = route.params.userId;

Refs:

1 Comment

I am facing errr in line const RootStack = createStackNavigator<RootStackParamList>(); Parsing error: Unexpected token (81:56)eslint Expression expected.ts(1109)
12

I solved this problem, it will help for now, but it's not the correct typing:

type Nav = {
  navigate: (value: string) => void;
}

const { navigate } = useNavigation<Nav>()

function foo() {
  navigate("Home")
}

1 Comment

Yeah, who really needs all of that type-checking, right?
8

While the other answers cover a good amount, I think I may add to this by describing usage in the useNavigation hook as well as passing the {navigation} through props to a screen.

First, setup the Stack Navigator:

/**
* Types for Stack Navigator.
*/
export type StackParamList = {
  Main: undefined;
  Home: undefined;
};

const Stack = createStackNavigator<StackParamList>();
  • When using the useNavigation hook:
import { StackNavigationProp } from "@react-navigation/stack";

/**
 * Types for the Stack Navigator.
 */
export type StackNavigation = StackNavigationProp<StackParamList>;

const navigation = useNavigation<StackNavigation>();
  • When passing the navigation down as a prop in a screen:
/**
 * Types for passing the navigation props to screens in the Bottom Tab Navigator.
*/
export type StackNavigationProps = {
  navigation: StackNavigation;
};

const SomeScreenInTheStack = ({ navigation }: StackNavigationProps) => {
...
}

Hope this is useful to someone!

Comments

1

Easy way for this is:

navigation.navigate('Main' as never)}

Comments

1

I think the best way is this:

  1. create a file @types/index.ts
    Inside this file, paste the code:
type Routes = {
  routeNames: never[];
};

export type navigationProps = {
  navigate: (screen?: string) => void;
  goBack: () => void;
  reset: (index: number, routeNames: Routes[]) => void;
};

  1. Now you just need to use the navigationProps as the generic of useNavigation example:
import { useNavigation } from '@react-navigation/native';

const navigation = useNavigation<navigationProps>();

Comments

-3

You can just put a Type on the screen name. Just like:

const handleContinue = () => navigation.navigate('Login' as never);

1 Comment

That's not a good practice. I'm not the downvoter.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.