Skip to content

Commit

Permalink
Merge TypeScript & Static TypeScript docs
Browse files Browse the repository at this point in the history
  • Loading branch information
satya164 committed Feb 28, 2024
1 parent 4ce1b1c commit 6765a7c
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 119 deletions.
117 changes: 0 additions & 117 deletions versioned_docs/version-7.x/static-typescript.md

This file was deleted.

128 changes: 127 additions & 1 deletion versioned_docs/version-7.x/typescript.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,130 @@ title: Type checking with TypeScript
sidebar_label: Type checking with TypeScript
---

React Navigation is written with TypeScript and exports type definitions for TypeScript projects.
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

React Navigation can be configured to type-check screens and their params, as well as various other APIs using TypeScript. This provides better intelliSense and type safety when working with React Navigation.

<Tabs groupId="config" queryString="config">
<TabItem value="static" label="Static" default>

There are 2 steps to configure TypeScript with the static API:

1. Each screen component needs to specify the type of the `route.params` prop that it accepts. The `StaticScreenProps` type makes it simpler:

```ts
import type { StaticScreenProps } from '@react-navigation/native';

type Props = StaticScreenProps<{
username: string;
}>;

function ProfileScreen({ route }: Props) {
// ...
}
```

1. Generate the `ParamList` type for the root navigator and specify it as the default type for the `RootParamList` type:

```ts
import type { StaticParamList } from '@react-navigation/native';

const HomeTabs = createBottomTabNavigator({
screens: {
Feed: FeedScreen,
Profile: ProfileScreen,
},
});

const RootStack = createNativeStackNavigator({
screens: {
Home: HomeTabs,
},
});

type RootStackParamList = StaticParamList<typeof RootStack>;

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

This is needed to type-check the `useNavigation` hook.

## Navigator specific types

Generally we recommend using the default types for the `useNavigation` prop to access the navigation object in a navigator agnostic manner. However, if you need to use navigator specific APIs, you need to manually annotate `useNavigation`:

```ts
type BottomTabParamList = StaticParamList<typeof BottomTabNavigator>;
type ProfileScreenNavigationProp = BottomTabNavigationProp<
BottomTabParamList,
'Profile'
>;

// ...

const navigation = useNavigation<ProfileScreenNavigationProp>();
```

This follows the same principle as the types described in [Type checking with TypeScript](typescript.md).

Note that annotating `useNavigation` this way not type-safe since we can't guarantee that the type you provided matches the type of the navigator.

## Nesting navigator using dynamic API

Consider the following example:

```js
const Tab = createBottomTabNavigator();

function HomeTabs() {
return (
<Tab.Navigator>
<Tab.Screen name="Feed" component={FeedScreen} />
<Tab.Screen name="Profile" component={ProfileScreen} />
</Tab.Navigator>
);
}

const RootStack = createStackNavigator({
Home: HomeTabs,
});
```

Here, the `HomeTabs` component is defined using the dynamic API. This means that when we create the param list for the root navigator with `StaticParamList<typeof RootStack>`, it won't know about the screens defined in the nested navigator. To fix this, we'd need to specify the param list for the nested navigator explicitly.

This can be done by using the type of the `route` prop that the screen component receives:

```ts
type HomeTabsParamList = {
Feed: undefined;
Profile: undefined;
};

type HomeTabsProps = StaticScreenProps<
NavigatorScreenParams<HomeTabsParamList>
>;

function HomeTabs(_: HomeTabsProps) {
return (
<Tab.Navigator>
<Tab.Screen name="Feed" component={FeedScreen} />
<Tab.Screen name="Profile" component={ProfileScreen} />
</Tab.Navigator>
);
}
```

Now, when using `StaticParamList<typeof RootStack>`, it will include the screens defined in the nested navigator.

</TabItem>
<TabItem value="dynamic" label="Dynamic">

When using the dynamic API, it is necessary to specify the types for each screen as well as the nesting structure as it cannot be inferred from the code.

### Type checking the navigator

Expand Down Expand Up @@ -389,3 +512,6 @@ function PopularScreen() {
// ...
}
```

</TabItem>
</Tabs>
1 change: 0 additions & 1 deletion versioned_sidebars/version-7.x-sidebars.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
],
"Static configuration": [
"static-api-reference",
"static-typescript",
"static-authentication",
"static-combine-with-dynamic"
],
Expand Down

0 comments on commit 6765a7c

Please sign in to comment.