Skip to content

Commit 6765a7c

Browse files
committed
Merge TypeScript & Static TypeScript docs
1 parent 4ce1b1c commit 6765a7c

File tree

3 files changed

+127
-119
lines changed

3 files changed

+127
-119
lines changed

versioned_docs/version-7.x/static-typescript.md

Lines changed: 0 additions & 117 deletions
This file was deleted.

versioned_docs/version-7.x/typescript.md

Lines changed: 127 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,130 @@ title: Type checking with TypeScript
44
sidebar_label: Type checking with TypeScript
55
---
66

7-
React Navigation is written with TypeScript and exports type definitions for TypeScript projects.
7+
import Tabs from '@theme/Tabs';
8+
import TabItem from '@theme/TabItem';
9+
10+
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.
11+
12+
<Tabs groupId="config" queryString="config">
13+
<TabItem value="static" label="Static" default>
14+
15+
There are 2 steps to configure TypeScript with the static API:
16+
17+
1. Each screen component needs to specify the type of the `route.params` prop that it accepts. The `StaticScreenProps` type makes it simpler:
18+
19+
```ts
20+
import type { StaticScreenProps } from '@react-navigation/native';
21+
22+
type Props = StaticScreenProps<{
23+
username: string;
24+
}>;
25+
26+
function ProfileScreen({ route }: Props) {
27+
// ...
28+
}
29+
```
30+
31+
1. Generate the `ParamList` type for the root navigator and specify it as the default type for the `RootParamList` type:
32+
33+
```ts
34+
import type { StaticParamList } from '@react-navigation/native';
35+
36+
const HomeTabs = createBottomTabNavigator({
37+
screens: {
38+
Feed: FeedScreen,
39+
Profile: ProfileScreen,
40+
},
41+
});
42+
43+
const RootStack = createNativeStackNavigator({
44+
screens: {
45+
Home: HomeTabs,
46+
},
47+
});
48+
49+
type RootStackParamList = StaticParamList<typeof RootStack>;
50+
51+
declare global {
52+
namespace ReactNavigation {
53+
interface RootParamList extends RootStackParamList {}
54+
}
55+
}
56+
```
57+
58+
This is needed to type-check the `useNavigation` hook.
59+
60+
## Navigator specific types
61+
62+
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`:
63+
64+
```ts
65+
type BottomTabParamList = StaticParamList<typeof BottomTabNavigator>;
66+
type ProfileScreenNavigationProp = BottomTabNavigationProp<
67+
BottomTabParamList,
68+
'Profile'
69+
>;
70+
71+
// ...
72+
73+
const navigation = useNavigation<ProfileScreenNavigationProp>();
74+
```
75+
76+
This follows the same principle as the types described in [Type checking with TypeScript](typescript.md).
77+
78+
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.
79+
80+
## Nesting navigator using dynamic API
81+
82+
Consider the following example:
83+
84+
```js
85+
const Tab = createBottomTabNavigator();
86+
87+
function HomeTabs() {
88+
return (
89+
<Tab.Navigator>
90+
<Tab.Screen name="Feed" component={FeedScreen} />
91+
<Tab.Screen name="Profile" component={ProfileScreen} />
92+
</Tab.Navigator>
93+
);
94+
}
95+
96+
const RootStack = createStackNavigator({
97+
Home: HomeTabs,
98+
});
99+
```
100+
101+
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.
102+
103+
This can be done by using the type of the `route` prop that the screen component receives:
104+
105+
```ts
106+
type HomeTabsParamList = {
107+
Feed: undefined;
108+
Profile: undefined;
109+
};
110+
111+
type HomeTabsProps = StaticScreenProps<
112+
NavigatorScreenParams<HomeTabsParamList>
113+
>;
114+
115+
function HomeTabs(_: HomeTabsProps) {
116+
return (
117+
<Tab.Navigator>
118+
<Tab.Screen name="Feed" component={FeedScreen} />
119+
<Tab.Screen name="Profile" component={ProfileScreen} />
120+
</Tab.Navigator>
121+
);
122+
}
123+
```
124+
125+
Now, when using `StaticParamList<typeof RootStack>`, it will include the screens defined in the nested navigator.
126+
127+
</TabItem>
128+
<TabItem value="dynamic" label="Dynamic">
129+
130+
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.
8131

9132
### Type checking the navigator
10133

@@ -389,3 +512,6 @@ function PopularScreen() {
389512
// ...
390513
}
391514
```
515+
516+
</TabItem>
517+
</Tabs>

versioned_sidebars/version-7.x-sidebars.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
],
4343
"Static configuration": [
4444
"static-api-reference",
45-
"static-typescript",
4645
"static-authentication",
4746
"static-combine-with-dynamic"
4847
],

0 commit comments

Comments
 (0)