使用 Typescript [react-navigation v6] 在嵌套导航器中获取路由参数时出现类型错误

Ami*_*avi 11 react-native react-navigation react-navigation-stack react-navigation-bottom-tab react-navigation-v6

导航类型定义如下,当我从 例如 导航AOne到时BTwo,控制台id:99 日志props.route.params显示正确的信息。但props.route.params.id抛出类型错误

类型错误:未定义不是对象(正在评估“props.route.params.id”)

    // navigation related imports in all components 
    import {BottomTabScreenProps} from '@react-navigation/bottom-tabs';
    import {CompositeScreenProps, NavigatorScreenParams} from '@react-navigation/core';
    import {StackScreenProps} from '@react-navigation/stack';

    // type defenitions
    export type StackOneParams = {
      AOne:undefined,
      BOne: undefined,
      // some other screens
    };
    export type StackTwoParams = {
      ATwo: undefined;
      BTwo:{id:number};
      // some other screens
    };
    
    export type TabParams = {
      StackOne: NavigatorScreenParams<StackOneParams>;
      StackTwo: NavigatorScreenParams<StackTwoParams>;
    // ... some other stacks each represent a tab 
    };

    export type RootParamList = {
       ROne: undefined;  // these screens should stand alone and not blong to any tab
       RTwo: undefined;
       Tabs: NavigatorScreenParams<TabParams>
    }

    // navigation from AOne to BTwo
      props.navigation.navigate('Tabs', {
         screen: 'StackTwo',
         params: {screen: 'BTwo', params: {id: 99}}
     }); // this part give correct auto complete hints in VSCode and no compilation error

 // BTwo component (screen)
//--------------------------------
    type Props = CompositeScreenProps<
  StackScreenProps<RootParamList, 'Tabs'>,
  CompositeScreenProps<
    BottomTabScreenProps<TabPrams, 'StackTwo'>,
    StackScreenProps<StackTwoParams, 'BTwo'>
  >
>;// using CompositeScreenProps to be able to navigate to screens in another tabs
// otherwise just `type Props=StackScreenProps<StackTwoParams, 'BTwo'>` works fine but cannot navigate to other tabs


    const BTwo:React.FC<Props> = (props) =>{
    console.log(props.route.params)// the log shows {id:23} 
    // but props.route.params.id gives error and also no auto completion hint 
       return(...)
    }
Run Code Online (Sandbox Code Playgroud)
  • 这是为特定屏幕定义屏幕道具的正确方法吗,就像我在 BTwo 屏幕中所使用的那样?或者构图的顺序应该不同?

大多数示例(和官方文档)显示了最简单的组合,其中目标屏幕甚至不在第二级嵌套中(在官方文档中profile并不是真正在嵌套的底部选项卡中)

在这种情况下我应该如何解决类型错误?

该图显示了 VSCode 自动完成建议

在此输入图像描述

Dav*_*olz 8

使用 CompositeScreenProps 的解决方案

我的其他解释不太准确。您定义的方式CompositeScreenProp不正确。这是实现此目的的正确方法。

type ScreenProps = CompositeScreenProps<
  StackScreenProps<StackTwoParams, "BTwo">,
  CompositeScreenProps<
    BottomTabScreenProps<TabParams, "StackTwo">, 
    StackScreenProps<RootParamList>
  >
>
Run Code Online (Sandbox Code Playgroud)

第一个参数包含拥有屏幕的CompositeScreenProps导航器的类型。在本例中,由所有者拥有,这决定了主导航器,即.BTwoStackTwoStack

上述也产生了正确的类型。

const BTwo = (props: ScreenProps) => {
  return <></>
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

在此输入图像描述


使用单独类型进行导航和路线的解决方案

我们可以分别输入导航对象和路线对象,如下所示。

type NavigationProps = CompositeNavigationProp<
  StackNavigationProp<StackTwoParams, "BTwo">,
  CompositeNavigationProp<
    BottomTabNavigationProp<TabParams, "StackTwo">, 
    StackNavigationProp<RootParamList>
  >
>

type ScreenPropsA = {
  navigation: NavigationProps
  route: RouteProp<StackTwoParams, "BTwo">
}
Run Code Online (Sandbox Code Playgroud)

CompositeNavigationProp请注意此处和 的用法RouteProp

然后,按如下方式使用它。


const BTwo = ({ route, navigation }: ScreenProps) => {

  return <></>
}
Run Code Online (Sandbox Code Playgroud)

两者routenavigation现在都已正确键入。

在此输入图像描述

在此输入图像描述

在此输入图像描述