Creating a Parameter List for nested navigators with v5: Key steps to follow

If I have two navigators structured like this:

export type RootStackParamList = {
  Bootstrap: undefined;
  Login: undefined;
  MainApp: undefined;
};

export type MainTabsParamList = {
  Explore: undefined;
  Profile: undefined;
};

const MainTabs = createBottomTabNavigator<MainTabsParamList>();
const MainApp = () => (
  <MainTabs.Navigator >
    <MainTabs.Screen
      name="Explore"
      component={Explore}
    />
    <MainTabs.Screen
      name="Profile"
      component={Profile}
    />
  </MainTabs.Navigator>
);

const RootStack = createStackNavigator<RootStackParamList>();
const App = () => {
  return (
    <NavigationContainer>
      <RootStack.Navigator initialRouteName="Bootstrap" headerMode="none">
        <RootStack.Screen name="Bootstrap" component={Bootstrap} />
        <RootStack.Screen name="Login" component={Login} />
        <RootStack.Screen name="MainApp" component={MainApp} />
      </RootStack.Navigator>
    </NavigationContainer>
  );
};

To navigate to the Profile screen from the Bootstrap screen, you would typically write: (assuming proper annotation of navigation prop)

navigation.navigate('MainApp', {screen: 'Profile'})

However, TypeScript may give an error in this scenario, stating that

Type '{ screen: string; }' is not assignable to type 'undefined'
. This occurs because TypeScript doesn't recognize that MainApp has child screens. To address this, you need to somehow compose the ParamLists so TypeScript understands the child screens. Is there a way to achieve this with react-navigation v5?

Answer №1

Seems like there isn't a straightforward solution readily available, HOWEVER I stumbled upon this interesting discussion thread (issue). Maybe we can find a useful fix there.

type NestedNavigatorParams<ParamList> = {
  [K in keyof ParamList]: undefined extends ParamList[K]
    ? { screen: K; params?: ParamList[K] }
    : { screen: K; params: ParamList[K] }
}[keyof ParamList]

It's quite simple to implement:

export type MainTabsParamList = {
  Explore: undefined;
  Profile: undefined;
};

export type RootStackParamList = {
  Bootstrap: undefined;
  Login: undefined;
  MainApp: NestedNavigatorParams<MainTabsParamList>;
};

Answer №2

Update as of February 15, 2022: It appears that a ready-made solution is now available :D

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

export type RootStackParamList = {
  Bootstrap: undefined;
  Login: undefined;
  MainApp: NavigatorScreenParams<MainTabsParamList>;
};

export type MainTabsParamList = {
  Explore: undefined;
  Profile: undefined;
};

For further reference, please visit the documentation here: https://reactnavigation.org/docs/typescript/#type-checking-screens-and-params-in-nested-navigator

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Do not consider node_modules folder in the list of "issues"

Currently, I am executing the following task: { "taskName": "tsc watch", "command": "tsc -w", "type": "shell", "problemMatcher": "$tsc-watch" } using this specific tsconfig setup: { "compileOnSave": true, "files": ...

Typescript filtering function that results in an empty array

Struggling with filtering an array in typescript and aurelia as I keep getting empty lists. For example, when searching for the keyword ra within the firstName property, I expect to retrieve the object with the name "Raja". Not sure where I'm going w ...

Conditional type in Typescript can be used to infer tuple types

Why are output1 and output2 not both inferred as [number, number, number] in the following code snippets? Snippet 1 : type InferTuple1<T> = T extends any[] ? [...T]: never; const func1 = <T>(t: InferTuple1<T>) => t; const output1 = ...

Steps for creating an npm package using a custom react-native native module for Android

Question: I developed a native component for react-native Android with its own dependencies. After editing the package.json as instructed, removing react-native dependencies, and testing the package, I am encountering issues. Are there specific guidelines ...

The functionality of NgbModal in ng-bootstrap is experiencing issues and becoming unresponsive in ng-bootstrap version 15 and Angular version 16

Currently, I am in the process of upgrading my Angular app from version 15 to version 16. Following the documentation, I have updated the @ng-bootstrap/ng-bootstrap package to version 15. However, after this update, I am facing issues with the NgbModals no ...

Installation and execution of TypeScript jQuery / Bootstrap definition file on a local machine using npm typings: A step-by-step guide

Struggling to set up TypeScript jQuery and Bootstrap definition files in my new project using npm typings. Below are the steps I followed: 1- Open cmd, navigate to my project folder, and enter the following commands: npm install typings --global typings ...

Provide the remaining arguments in a specific callback function in TypeScript while abiding by strict mode regulations

In my code, I have a function A that accepts another function as an argument. Within function A, I aim to run the given function with one specific parameter and the remaining parameters from the given function. Here's an example: function t(g: number, ...

The culprit behind Angular 11 app error: Unidentified router outlet triggering 'No routes match' issue

In my Angular 11 application, I am utilizing a named router-outlet. The setup in my app.component.html file looks like this: <ng-container *ngIf="showGeneric"> <router-outlet name="general"> </router-o ...

Adjust an IntervalObservable's interval by incorporating a variable

I've encountered an issue with a component that needs to run code at regular intervals without pausing. I'm currently using an IntervalObservable and need to adjust the interval dynamically. While I can change the variable value using the setTime ...

Issue: Angular is indicating that the 'feedbackFormDirective' member is implicitly assigned with type 'any'

I am encountering an error in my project while using Angular version 12. Despite extensive research, I have been unable to find a solution. Here is my .ts file: import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { Feedba ...

Nestjs is throwing an UnhandledPromiseRejectionWarning due to a TypeError saying that the function this.flushLogs is not recognized

Looking to dive into the world of microservices using kafka and nestjs, but encountering an error message like the one below: [Nest] 61226 - 07/18/2021, 12:12:16 PM [NestFactory] Starting Nest application... [Nest] 61226 - 07/18/2021, 12:12:16 PM [ ...

I'm having trouble understanding why I can't access the properties of a class within a function that has been passed to an Angular

Currently, I have integrated HTML 5 geolocation into an Angular component: ... export class AngularComponent { ... constructor(private db: DatabaseService) {} // this function is linked to an HTML button logCoords(message, ...

Compiling TypeScript files from multiple source directories

Having 3 NodeJs applications with the latest versions of Typescript code, each containing an "src" folder with TypeScript code files and a "dist" folder with JavaScript files compiled by Typescript. I am now looking to create a "common" folder outside of ...

Transforming the express app object into a data type instead of a regular variable

Currently, I am setting up my own TypeScript Express project and aiming to abstract the code for better organization. In my app.ts file, the code looks like this: import express from 'express' const app = express(); const port = 3000; require( ...

Send a function as a parameter to another component, but it remains dormant

I am attempting to control the enable and disable state of a button based on changes in a value. To achieve this, I have defined a model as follows: export class Model{ label:string=''; isEnabled:Function=()=>true; } The component1 i ...

Angular 2 template can randomly display elements by shuffling the object of objects

I am working with a collection of objects that have the following structure: https://i.stack.imgur.com/ej63v.png To display all images in my template, I am using Object.keys Within the component: this.objectKeys = Object.keys; In the template: <ul ...

Tailoring Aurelia for .cshtml integration

I stumbled upon an informative article detailing the integration of Razor partials (cshtml) with aurelia. Despite my efforts, I encountered difficulty in getting the code to execute properly and was informed by Rob Eisenberg's comment that Convention ...

Switch up your component button in Angular across various pages

I've created a new feature within a component that includes a toolbar with multiple buttons. Is there a way to customize these buttons for different pages where the component is used? Component name <app-toolbar></app-toolbar> Component ...

Indicate the type of method without transforming it into a property

If I have a method in my application that delegates its functionality to an external library method, and I know the type for that external method (e.g. LibDoStuffMethodType), how can I specify the type for my method MyApp.doStuff() without making it a prop ...

Starting from TypeScript version 5.6, `Buffer` cannot be categorized as either `ArrayBufferView` or `Uint8Array | DataView`

Struggling to make the transition to TypeScript 5.6 Beta, I am encountering these error messages within the node_modules directory. Without making any other modifications, how can I resolve these errors? node_modules/@types/node/buffer.d.ts:632:19 - error ...