Skip to content
This repository has been archived by the owner on Feb 8, 2020. It is now read-only.

Commit

Permalink
refactor: tweak types
Browse files Browse the repository at this point in the history
  • Loading branch information
satya164 committed Jul 22, 2019
1 parent cbfbf4e commit 2de206c
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 46 deletions.
8 changes: 4 additions & 4 deletions src/NavigationContext.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import * as React from 'react';
import { NavigationProp } from './types';
import { NavigationProp, ParamListBase } from './types';

const NavigationContext = React.createContext<NavigationProp | undefined>(
undefined
);
const NavigationContext = React.createContext<
NavigationProp<ParamListBase> | undefined
>(undefined);

export default NavigationContext;
13 changes: 7 additions & 6 deletions src/SceneView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,32 @@ import StaticContainer from './StaticContainer';
import EnsureSingleNavigator from './EnsureSingleNavigator';
import {
Route,
ParamListBase,
NavigationState,
NavigationProp,
RouteConfig,
TargetRoute,
} from './types';

type Props = {
screen: RouteConfig;
navigation: NavigationProp;
route: Route & { state?: NavigationState };
type Props<ScreenOptions extends object> = {
screen: RouteConfig<ParamListBase, string, ScreenOptions>;
navigation: NavigationProp<ParamListBase>;
route: Route<string> & { state?: NavigationState };
getState: () => NavigationState;
setState: (state: NavigationState) => void;
setOptions: (
cb: (options: { [key: string]: object }) => { [key: string]: object }
) => void;
};

export default function SceneView({
export default function SceneView<ScreenOptions extends object>({
screen,
route,
navigation: helpers,
getState,
setState,
setOptions,
}: Props) {
}: Props<ScreenOptions>) {
const { performTransaction } = React.useContext(NavigationStateContext);

const navigation = React.useMemo(
Expand Down
8 changes: 6 additions & 2 deletions src/Screen.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { RouteConfig } from './types';
import { RouteConfig, ParamListBase } from './types';

export default function Screen(_: RouteConfig) {
export default function Screen<
ParamList extends ParamListBase,
RouteName extends keyof ParamList,
ScreenOptions extends object
>(_: RouteConfig<ParamList, RouteName, ScreenOptions>) {
/* istanbul ignore next */
return null;
}
22 changes: 11 additions & 11 deletions src/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export type NavigationState = {
/**
* List of rendered routes.
*/
routes: Array<Route & { state?: NavigationState }>;
routes: Array<Route<string> & { state?: NavigationState }>;
};

export type PartialState = Omit<Omit<NavigationState, 'routeNames'>, 'key'> & {
Expand All @@ -32,7 +32,7 @@ export type PartialState = Omit<Omit<NavigationState, 'routeNames'>, 'key'> & {
state?: PartialState;
};

export type Route<RouteName = string> = {
export type Route<RouteName extends string> = {
/**
* Unique key for the route.
*/
Expand All @@ -51,11 +51,11 @@ export type NavigationAction = {
type: string;
};

export type ActionCreators<Action extends NavigationAction = CommonAction> = {
export type ActionCreators<Action extends NavigationAction> = {
[key: string]: (...args: any) => Action;
};

export type Router<Action extends NavigationAction = CommonAction> = {
export type Router<Action extends NavigationAction> = {
/**
* Initialize the navigation state.
*
Expand Down Expand Up @@ -150,8 +150,8 @@ class PrivateValueStore<T> {
}

export type NavigationProp<
ParamList extends ParamListBase = ParamListBase,
ScreenOptions extends object = object
ParamList extends ParamListBase,
ScreenOptions extends object = {}
> = {
/**
* Dispatch an action or an update function to the router.
Expand Down Expand Up @@ -224,7 +224,7 @@ export type NavigationProp<
export type RouteProp<
ParamList extends ParamListBase,
RouteName extends keyof ParamList
> = Omit<Route<RouteName>, 'params'> &
> = Omit<Route<Extract<RouteName, string>>, 'params'> &
(ParamList[RouteName] extends undefined
? {}
: {
Expand Down Expand Up @@ -258,9 +258,9 @@ export type Descriptor<ScreenOptions extends object> = {
};

export type RouteConfig<
ParamList extends ParamListBase = ParamListBase,
RouteName extends keyof ParamList = string,
ScreenOptions extends object = object
ParamList extends ParamListBase,
RouteName extends keyof ParamList,
ScreenOptions extends object
> = {
/**
* Route name of this screen.
Expand All @@ -274,7 +274,7 @@ export type RouteConfig<
| ScreenOptions
| ((props: {
route: RouteProp<ParamList, RouteName>;
navigation: NavigationProp<ParamList>;
navigation: NavigationProp<ParamList, ScreenOptions>;
}) => ScreenOptions);

/**
Expand Down
14 changes: 7 additions & 7 deletions src/useDescriptors.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ import NavigationBuilderContext, {
ChildActionListener,
} from './NavigationBuilderContext';

type Options = {
type Options<ScreenOptions extends object> = {
state: NavigationState | PartialState;
screens: { [key: string]: RouteConfig<ParamListBase, string> };
screens: { [key: string]: RouteConfig<ParamListBase, string, ScreenOptions> };
navigation: NavigationProp<ParamListBase>;
onAction: (action: NavigationAction, sourceNavigatorKey?: string) => boolean;
getState: () => NavigationState;
Expand All @@ -35,7 +35,7 @@ export default function useDescriptors<ScreenOptions extends object>({
addActionListener,
removeActionListener,
onRouteFocus,
}: Options) {
}: Options<ScreenOptions>) {
const [options, setOptions] = React.useState<{ [key: string]: object }>({});
const context = React.useMemo(
() => ({
Expand Down Expand Up @@ -74,13 +74,13 @@ export default function useDescriptors<ScreenOptions extends object>({
);
},
options: {
...(typeof screen.options === 'function'
? screen.options({
...(typeof screen.options === 'object' || screen.options == null
? screen.options
: screen.options({
// @ts-ignore
route,
navigation,
})
: screen.options),
})),
...options[route.key],
},
};
Expand Down
26 changes: 19 additions & 7 deletions src/useNavigationBuilder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import useRegisterNavigator from './useRegisterNavigator';
import useDescriptors from './useDescriptors';
import useNavigationHelpers from './useNavigationHelpers';
import useOnAction from './useOnAction';
import { Router, NavigationState, RouteConfig } from './types';
import { Router, NavigationState, RouteConfig, ParamListBase } from './types';
import useOnRouteFocus from './useOnRouteFocus';
import useChildActionListeners from './useChildActionListeners';

Expand All @@ -17,16 +17,26 @@ type Options = {
const isArrayEqual = (a: any[], b: any[]) =>
a.length === b.length && a.every((it, index) => it === b[index]);

const getRouteConfigsFromChildren = (children: React.ReactNode) =>
React.Children.toArray(children).reduce<RouteConfig[]>((acc, child) => {
const getRouteConfigsFromChildren = <ScreenOptions extends object>(
children: React.ReactNode
) =>
React.Children.toArray(children).reduce<
RouteConfig<ParamListBase, string, ScreenOptions>[]
>((acc, child) => {
if (React.isValidElement(child)) {
if (child.type === Screen) {
acc.push(child.props as RouteConfig);
acc.push(child.props as RouteConfig<
ParamListBase,
string,
ScreenOptions
>);
return acc;
}

if (child.type === React.Fragment) {
acc.push(...getRouteConfigsFromChildren(child.props.children));
acc.push(
...getRouteConfigsFromChildren<ScreenOptions>(child.props.children)
);
return acc;
}
}
Expand All @@ -45,12 +55,14 @@ export default function useNavigationBuilder<ScreenOptions extends object>(
) {
useRegisterNavigator();

const screens = getRouteConfigsFromChildren(options.children).reduce(
const screens = getRouteConfigsFromChildren<ScreenOptions>(
options.children
).reduce(
(acc, curr) => {
acc[curr.name] = curr;
return acc;
},
{} as { [key: string]: RouteConfig }
{} as { [key: string]: RouteConfig<ParamListBase, string, ScreenOptions> }
);

const routeNames = Object.keys(screens);
Expand Down
11 changes: 6 additions & 5 deletions src/useNavigationHelpers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,26 @@ import {
NavigationAction,
NavigationState,
ActionCreators,
ParamListBase,
} from './types';

type Options = {
type Options<Action extends NavigationAction> = {
onAction: (action: NavigationAction, sourceNavigatorKey?: string) => boolean;
getState: () => NavigationState;
setState: (state: NavigationState) => void;
actionCreators?: ActionCreators;
actionCreators?: ActionCreators<Action>;
};

export default function useNavigationHelpers({
export default function useNavigationHelpers<Action extends NavigationAction>({
onAction,
getState,
setState,
actionCreators,
}: Options) {
}: Options<Action>) {
const parentNavigationHelpers = React.useContext(NavigationContext);
const { performTransaction } = React.useContext(NavigationStateContext);

return React.useMemo((): NavigationProp => {
return React.useMemo((): NavigationProp<ParamListBase> => {
const dispatch = (
action: NavigationAction | ((state: NavigationState) => NavigationState)
) => {
Expand Down
8 changes: 4 additions & 4 deletions src/useOnRouteFocus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@ import * as React from 'react';
import { NavigationAction, NavigationState, Router } from './types';
import NavigationBuilderContext from './NavigationBuilderContext';

type Options = {
router: Router;
type Options<Action extends NavigationAction> = {
router: Router<Action>;
onAction: (action: NavigationAction, sourceNavigatorKey?: string) => boolean;
getState: () => NavigationState;
setState: (state: NavigationState) => void;
key?: string;
};

export default function useOnRouteFocus({
export default function useOnRouteFocus<Action extends NavigationAction>({
router,
onAction,
getState,
key: sourceNavigatorKey,
setState,
}: Options) {
}: Options<Action>) {
const {
onRouteFocus: onRouteFocusParent,
addActionListener: addActionListenerParent,
Expand Down

0 comments on commit 2de206c

Please sign in to comment.