From f2b858e68f4c06db40dad388805b14ddac829963 Mon Sep 17 00:00:00 2001 From: doomsower Date: Fri, 23 Mar 2018 16:49:30 +0300 Subject: [PATCH] Some changes to react-navigation --- types/react-navigation/index.d.ts | 31 ++++++++--- .../react-navigation-tests.tsx | 52 ++++++++++++++++++- 2 files changed, 73 insertions(+), 10 deletions(-) diff --git a/types/react-navigation/index.d.ts b/types/react-navigation/index.d.ts index 0e6bb2d94c..379a24d4ba 100644 --- a/types/react-navigation/index.d.ts +++ b/types/react-navigation/index.d.ts @@ -77,7 +77,7 @@ export interface NavigationState { export type NavigationRoute = NavigationLeafRoute | NavigationStateRoute; -export interface NavigationLeafRoute { +export interface NavigationLeafRoute

{ /** * React's key used by some navigators. No need to specify these manually, * they will be defined by the router. @@ -96,7 +96,7 @@ export interface NavigationLeafRoute { * Params passed to this route when navigating to it, * e.g. `{ car_id: 123 }` in a route that displays a car. */ - params?: NavigationParams; + params?: P; } export type NavigationStateRoute = NavigationLeafRoute & NavigationState; @@ -175,6 +175,7 @@ export type NavigationScreenConfig = export type NavigationComponent = NavigationScreenComponent + | NavigationStatelessScreen | NavigationNavigator; export interface NavigationScreenComponent extends React.ComponentClass { @@ -299,7 +300,7 @@ export interface NavigationStackRouterConfig { initialRouteName?: string; initialRouteParams?: NavigationParams; paths?: NavigationPathsConfig; - navigationOptions?: NavigationScreenConfig; + navigationOptions?: NavigationScreenConfig; } export type NavigationStackAction = @@ -339,7 +340,7 @@ export interface NavigationPathsConfig { export interface NavigationTabRouterConfig { initialRouteName?: string; paths?: NavigationPathsConfig; - navigationOptions?: NavigationScreenConfig; + navigationOptions?: NavigationScreenConfig; order?: string[]; // todo: type these as the real route names rather than 'string' // Does the back button cause the router to switch to the initial tab @@ -433,7 +434,8 @@ export interface NavigationScreenProp { params?: P, action?: NavigationAction, ): boolean; - setParams: (newParams: NavigationParams) => boolean; + getParam: (param: T, fallback?: P[T]) => P[T]; + setParams: (newParams: P) => boolean; addListener: ( eventName: string, callback: NavigationEventCallback @@ -853,12 +855,25 @@ export function createNavigationContainer( * BEGIN CUSTOM CONVENIENCE INTERFACES */ -export interface NavigationScreenProps { - navigation: NavigationScreenProp; +export interface NavigationScreenProps

{ + navigation: NavigationScreenProp; screenProps?: { [key: string]: any }; - navigationOptions?: NavigationScreenConfig; + navigationOptions?: NavigationScreenConfig; } +export type AnyScreenOptions = + NavigationDrawerScreenOptions & + NavigationStackScreenOptions & + NavigationTabScreenOptions; + +export interface NavigationScreenStatic { + navigationOptions?: NavigationScreenConfig; +} + +export type NavigationStatelessScreen = + React.StatelessComponent> & + NavigationScreenStatic; + /** * END CUSTOM CONVENIENCE INTERFACES */ diff --git a/types/react-navigation/react-navigation-tests.tsx b/types/react-navigation/react-navigation-tests.tsx index d0e65dfc8e..496009688e 100644 --- a/types/react-navigation/react-navigation-tests.tsx +++ b/types/react-navigation/react-navigation-tests.tsx @@ -36,6 +36,10 @@ import { NavigationParams, NavigationPopAction, NavigationPopToTopAction, + NavigationScreenStatic, + NavigationScreenConfig, + AnyScreenOptions, + NavigationStatelessScreen, } from 'react-navigation'; // Constants @@ -84,12 +88,24 @@ class StartScreen extends React.Component { const ROUTE_NAME_NEXT_SCREEN = "NextScreen"; -class NextScreen extends React.Component { +interface NextScreenParams { + id: string; + name: string; +} + +class NextScreen extends React.Component> { + static navigationOptions: NavigationScreenConfig = { + tabBarLabel: 'Next tab', + drawerLabel: 'Next drawe label', + }; + render() { // Implicit type checks. const navigationStateParams = this.props.navigation.state.params; + // typeof id is any const id = this.props.navigation.state.params && this.props.navigation.state.params.id; - const name = this.props.navigation.state.params && this.props.navigation.state.params.name; + // typeof name is string + const name = this.props.navigation.getParam('name', 'Peter'); return ( @@ -97,6 +113,29 @@ class NextScreen extends React.Component { } } +const ROUTE_NAME_ANOTHER_SCREEN = "AnotherScreen"; + +interface AnotherScreenParams { + color: string; +} + +interface AnotherScreenProps { + apolloData: number[]; // Demonstrates that screen can be wrapped into HOCs +} + +// View below compiles without TS errors, because props and navigation params are strongly typed +const AnotherScreen: NavigationStatelessScreen = ({ apolloData, navigation }) => ( + +) + +// Demonstrates overriding navigationOptions on static components +AnotherScreen.navigationOptions = ({ navigation, navigationOptions }) => ({ + drawerLabel: navigation.state.params!.color + ' screen', +}); + const navigationOptions = { headerBackTitle: null, }; @@ -113,6 +152,15 @@ const routeConfigMap: NavigationRouteConfigMap = { path: "next", screen: NextScreen, }, + // Demonstrates stateless screen + [ROUTE_NAME_ANOTHER_SCREEN]: { + path: "another", + screen: AnotherScreen, + navigationOptions: { + // Demonstrates that stack entries can set optins for tab navigation (for deeper use) + tabBarVisible: false, + } + }, }; export const AppNavigator = StackNavigator( routeConfigMap,