Allow arbitrary keys to be included in RoutesMap

* Resolve no-unnecessary-generics errors
* Related to conversation in faceyspacey/redux-first-router/#15
This commit is contained in:
Cory Deppen
2017-10-17 17:46:41 -05:00
parent 17f38a9945
commit 2357543d01
2 changed files with 80 additions and 47 deletions

View File

@@ -3,6 +3,7 @@
// Definitions by: Valbrand <https://github.com/Valbrand>
// viggyfresh <https://github.com/viggyfresh>
// janb87 <https://github.com/janb87>
// corydeppen <https://github.com/corydeppen>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.4
@@ -21,21 +22,24 @@ export type StateGetter = () => object;
export type RouteString = string;
export type RouteThunk = <S>(dispatch: Dispatch<S>, getState: StateGetter) => any | Promise<any>;
export type RouteThunk = (
dispatch: Dispatch<any>,
getState: StateGetter
) => any | Promise<any>;
export interface RouteObject {
path: string;
export type RouteObject<TKeys> = TKeys & {
capitalizedWords?: boolean;
toPath?(param: string, key?: string): string;
fromPath?(path: string, key?: string): string;
thunk?: RouteThunk;
navKey?: string;
}
path: string;
thunk?: RouteThunk;
fromPath?(path: string, key?: string): string;
toPath?(param: string, key?: string): string;
};
export type Route = RouteString | RouteObject;
export type Route<TKeys = {}> = RouteString | RouteObject<TKeys>;
export interface RoutesMap {
[key: string]: Route;
export interface RoutesMap<TKeys = {}> {
[key: string]: Route<TKeys>;
}
export interface ReceivedAction {
@@ -127,14 +131,25 @@ export interface HistoryLocation {
export type HistoryAction = string;
export type Listener = (location: HistoryLocation, action: HistoryAction) => void;
export type Listener = (
location: HistoryLocation,
action: HistoryAction
) => void;
export type ScrollBehavior = object;
export interface Router {
getStateForActionOriginal(action: object, state: Nullable<object>): Nullable<object>;
getStateForAction(action: object, state: Nullable<object>): Nullable<object>;
getPathAndParamsForState(state: object): { path: Nullable<string>, params: Nullable<Params> };
getStateForActionOriginal(
action: object,
state: Nullable<object>
): Nullable<object>;
getStateForAction(
action: object,
state: Nullable<object>
): Nullable<object>;
getPathAndParamsForState(
state: object
): { path: Nullable<string>; params: Nullable<Params> };
getActionForPathAndParams(path: string): Nullable<object>;
}
@@ -164,14 +179,14 @@ export interface NavigatorsConfig {
navigationAction: Nullable<NavigationAction>,
route: Nullable<Route>
): object;
navigationToAction<S>(
navigationToAction(
navigators: Navigators,
store: Store<S>,
store: Store<any>,
routesMap: RoutesMap,
action: object
): {
action: object,
navigationAction: Nullable<NavigationAction>
action: object;
navigationAction: Nullable<NavigationAction>;
};
}
@@ -180,9 +195,9 @@ export interface Options {
location?: string | SelectLocationState;
notFoundPath?: string;
scrollTop?: boolean;
onBeforeChange?<S>(dispatch: Dispatch<S>, getState: StateGetter): void;
onAfterChange?<S>(dispatch: Dispatch<S>, getState: StateGetter): void;
onBackNext?<S>(dispatch: Dispatch<S>, getState: StateGetter): void;
onBeforeChange?(dispatch: Dispatch<any>, getState: StateGetter): void;
onAfterChange?(dispatch: Dispatch<any>, getState: StateGetter): void;
onBackNext?(dispatch: Dispatch<any>, getState: StateGetter): void;
restoreScroll?(history: History): ScrollBehavior;
initialDispatch?: boolean;
querySerializer?: QuerySerializer;
@@ -196,7 +211,11 @@ export type ScrollUpdater = (performedByUser: boolean) => void;
export const NOT_FOUND: '@@redux-first-router/NOT_FOUND';
export function actionToPath(action: ReceivedAction, routesMap: RoutesMap, querySerializer?: QuerySerializer): string;
export function actionToPath(
action: ReceivedAction,
routesMap: RoutesMap,
querySerializer?: QuerySerializer
): string;
export function back(): void;
@@ -206,12 +225,16 @@ export function canGoBack(): boolean;
export function canGoForward(): boolean;
export function connectRoutes(history: History, routesMap: RoutesMap, options?: Options): {
reducer: Reducer<LocationState>,
middleware: Middleware,
thunk<S>(store: Store<S>): Promise<Nullable<RouteThunk>>,
enhancer: GenericStoreEnhancer,
initialDispatch?(): void
export function connectRoutes(
history: History,
routesMap: RoutesMap,
options?: Options
): {
reducer: Reducer<LocationState>;
middleware: Middleware;
thunk(store: Store<any>): Promise<Nullable<RouteThunk>>;
enhancer: GenericStoreEnhancer;
initialDispatch?(): void;
};
export function go(n: number): void;
@@ -224,7 +247,10 @@ export function next(): void;
export function nextPath(): string | void;
export function pathToAction(pathname: string, routesMap: RoutesMap): ReceivedAction;
export function pathToAction(
pathname: string,
routesMap: RoutesMap
): ReceivedAction;
export function prevPath(): string | void;

View File

@@ -9,16 +9,16 @@ import {
QuerySerializer
} from 'redux-first-router';
import {
createStore,
applyMiddleware,
Middleware,
MiddlewareAPI,
Store,
Dispatch,
compose,
Action,
GenericStoreEnhancer,
StoreEnhancerStoreCreator
createStore,
applyMiddleware,
Middleware,
MiddlewareAPI,
Store,
Dispatch,
compose,
Action,
GenericStoreEnhancer,
StoreEnhancerStoreCreator
} from 'redux';
import { History } from 'history';
@@ -28,24 +28,31 @@ declare var history: History;
type State = LocationState;
type StoreCreator = StoreEnhancerStoreCreator<State>;
const routesMap = {
HOME: '/'
const routesMap: RoutesMap<{ role: string }> = {
HOME: '/',
ADMIN: {
path: '/admin',
role: 'admin'
}
};
const {
reducer,
middleware,
enhancer,
initialDispatch
reducer,
middleware,
enhancer,
initialDispatch
} = connectRoutes(history, routesMap, {
initialDispatch: false
initialDispatch: false
});
const dumbMiddleware: Middleware = store => next => action => next(action);
const composedMiddleware = applyMiddleware(middleware, dumbMiddleware);
const storeEnhancer = compose<StoreCreator, StoreCreator, StoreCreator>(enhancer, composedMiddleware);
const storeEnhancer = compose<StoreCreator, StoreCreator, StoreCreator>(
enhancer,
composedMiddleware
);
const store = createStore(reducer, storeEnhancer);