Skip to content

Commit 4ccd84c

Browse files
committed
Remove implicit any from the router
1 parent 2fcdb4d commit 4ccd84c

File tree

2 files changed

+42
-22
lines changed

2 files changed

+42
-22
lines changed

ui/frontend/Router.tsx

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,29 @@
11
import React from 'react';
22

3-
import { createBrowserHistory as createHistory } from 'history';
4-
import { createRouter } from './uss-router';
3+
import { createBrowserHistory as createHistory, Path, Location } from 'history';
4+
import { createRouter, PlainOrThunk } from './uss-router';
55
import UssRouter from './uss-router/Router';
66

77
import qs from 'qs';
88
import Route from 'route-parser';
99

1010
import * as actions from './actions';
11+
import State from './state';
12+
import { Channel, Edition, Mode, Page } from './types';
1113

1214
const homeRoute = new Route('/');
1315
const helpRoute = new Route('/help');
1416

15-
const stateSelector = ({ page, configuration: { channel, mode, edition } }) => ({
17+
interface Substate {
18+
page: Page;
19+
configuration: {
20+
channel: Channel;
21+
mode: Mode;
22+
edition: Edition;
23+
}
24+
}
25+
26+
const stateSelector = ({ page, configuration: { channel, mode, edition } }: State): Substate => ({
1627
page,
1728
configuration: {
1829
channel,
@@ -21,7 +32,7 @@ const stateSelector = ({ page, configuration: { channel, mode, edition } }) => (
2132
},
2233
});
2334

24-
const stateToLocation = ({ page, configuration }) => {
35+
const stateToLocation = ({ page, configuration }: Substate): Partial<Path> => {
2536
switch (page) {
2637
case 'help': {
2738
return {
@@ -42,7 +53,7 @@ const stateToLocation = ({ page, configuration }) => {
4253
}
4354
};
4455

45-
const locationToAction = location => {
56+
const locationToAction = (location: Location): PlainOrThunk<State, actions.Action> | null => {
4657
const matchedHelp = helpRoute.match(location.pathname);
4758

4859
if (matchedHelp) {
@@ -61,7 +72,7 @@ const locationToAction = location => {
6172
export default class Router extends React.Component<RouterProps> {
6273
private router: any;
6374

64-
public constructor(props) {
75+
public constructor(props: RouterProps) {
6576
super(props);
6677

6778
const history = createHistory();

ui/frontend/uss-router/index.ts

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,37 @@
11
import { isEqual } from 'lodash';
2-
import { createStore } from 'redux';
3-
import { BrowserHistory } from 'history';
2+
import { createStore, Reducer, Store, Action, PreloadedState } from 'redux';
3+
import { BrowserHistory, Location, Path } from 'history';
4+
import { ThunkAction } from 'redux-thunk';
45

5-
interface CreateRouterArg {
6-
store: any;
7-
reducer: any;
6+
export type PlainOrThunk<St, A extends Action<any>> = A | ThunkAction<void, St, {}, A>;
7+
8+
// This is a... dense... attempt at saying "we accept any store with
9+
// any dispatch so long as it can handle the actions you create". It's
10+
// probably overly complicated, restrictive, and broad all at the same
11+
// time.
12+
interface CreateRouterArg<St, SubSt, A extends Action<any>> {
13+
store: Store<St, A> & { dispatch: (a: PlainOrThunk<St, A>) => void }; // |
14+
reducer: Reducer<St>;
815
history: BrowserHistory;
9-
stateSelector: any;
10-
stateToLocation: any;
11-
locationToAction: any;
16+
stateSelector: (state: St) => SubSt;
17+
stateToLocation: (substate: St) => Partial<Path>;
18+
locationToAction: (location: Location) => PlainOrThunk<St, A> | null;
1219
}
1320

1421
export interface RouterObject {
1522
provisionalLocation: any;
1623
}
1724

18-
export function createRouter({
25+
export function createRouter<St, SubSt, A extends Action<any>>({
1926
store,
2027
reducer,
2128
history,
2229
stateSelector,
2330
stateToLocation,
2431
locationToAction,
25-
}: CreateRouterArg): RouterObject {
32+
}: CreateRouterArg<St, SubSt, A>): RouterObject {
2633
let doingUpdateFromBrowser = false; // Avoid immediately PUSHing the state again
27-
let interestingPrevState;
34+
let interestingPrevState: SubSt;
2835

2936
// Watch changes to the Redux state
3037
store.subscribe(() => {
@@ -42,7 +49,7 @@ export function createRouter({
4249
}
4350
});
4451

45-
const dispatchBrowserLocationChange = nextLocation => {
52+
const dispatchBrowserLocationChange = (nextLocation: Location) => {
4653
const action = locationToAction(nextLocation);
4754
if (action) {
4855
doingUpdateFromBrowser = true;
@@ -66,11 +73,13 @@ export function createRouter({
6673
interestingPrevState = stateSelector(store.getState());
6774

6875
return {
69-
provisionalLocation: action => {
76+
provisionalLocation: (makeAction: () => A) => {
7077
const state = store.getState();
71-
const tempStore = createStore(reducer, state);
72-
const a = action();
73-
tempStore.dispatch(a);
78+
// This is a hack -- we know that our fully-constructed state is
79+
// valid as a "preloaded" state for a brand new store!
80+
const tempStore = createStore(reducer, state as PreloadedState<St>);
81+
const action = makeAction();
82+
tempStore.dispatch(action);
7483
const maybeState = tempStore.getState();
7584
return stateToLocation(maybeState);
7685
},

0 commit comments

Comments
 (0)