mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-02-10 22:47:02 +08:00
refactor: tweak types
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -5,16 +5,17 @@ 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: (
|
||||
@@ -22,14 +23,14 @@ type Props = {
|
||||
) => 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(
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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'> & {
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -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.
|
||||
*
|
||||
@@ -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.
|
||||
@@ -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
|
||||
? {}
|
||||
: {
|
||||
@@ -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.
|
||||
@@ -274,7 +274,7 @@ export type RouteConfig<
|
||||
| ScreenOptions
|
||||
| ((props: {
|
||||
route: RouteProp<ParamList, RouteName>;
|
||||
navigation: NavigationProp<ParamList>;
|
||||
navigation: NavigationProp<ParamList, ScreenOptions>;
|
||||
}) => ScreenOptions);
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
@@ -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(
|
||||
() => ({
|
||||
@@ -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],
|
||||
},
|
||||
};
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
) => {
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user