Skip to content

Commit

Permalink
Improve typing of Redux code
Browse files Browse the repository at this point in the history
  • Loading branch information
captbaritone committed May 7, 2024
1 parent 3f3808c commit 319f131
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 24 deletions.
4 changes: 2 additions & 2 deletions packages/webamp/js/reducers/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { AppState, Action } from "../types";
import { combineReducers } from "redux";
import { Reducer, combineReducers } from "redux";

import playlist from "./playlist";
import windows from "./windows";
Expand All @@ -12,7 +12,7 @@ import settings from "./settings";
import tracks from "./tracks";
import milkdrop from "./milkdrop";

const reducer = combineReducers<AppState, Action>({
const reducer: Reducer<AppState, Action, never> = combineReducers({
userInput,
windows,
display,
Expand Down
4 changes: 2 additions & 2 deletions packages/webamp/js/serialization.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as Selectors from "./selectors";
import * as Actions from "./actionCreators";
import { kebabCase } from "lodash";

import { createStore, applyMiddleware } from "redux";
import { legacy_createStore as createStore, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import { LOAD_SERIALIZED_STATE } from "./actionTypes";
import { SerializedStateV1 } from "./serializedStates/v1Types";
Expand Down Expand Up @@ -83,7 +83,7 @@ function testSerialization<T>({
function getStore() {
const extras = {};
const enhancer = applyMiddleware(thunk.withExtraArgument(extras));
return createStore(reducer, enhancer);
return createStore(reducer, undefined, enhancer);
}

describe("can serialize", () => {
Expand Down
47 changes: 27 additions & 20 deletions packages/webamp/js/store.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { createStore, applyMiddleware } from "redux";
import {
legacy_createStore as createStore,
applyMiddleware,
Middleware as ReduxMiddleware,
} from "redux";
import thunk from "redux-thunk";
import { composeWithDevTools } from "redux-devtools-extension";
import reducer from "./reducers";
Expand All @@ -7,20 +11,27 @@ import { merge } from "./utils";
import { UPDATE_TIME_ELAPSED, STEP_MARQUEE } from "./actionTypes";
import Media from "./media";
import Emitter from "./emitter";
import { Extras, Dispatch, Action, Middleware, PartialState } from "./types";
import {
Extras,
Dispatch,
Action,
PartialState,
Middleware,
Store,
} from "./types";

// TODO: Move to demo
const compose = composeWithDevTools({
actionsBlacklist: [UPDATE_TIME_ELAPSED, STEP_MARQUEE],
});

export default function (
export default function createWebampStore(
media: Media,
actionEmitter: Emitter,
customMiddlewares: Middleware[] = [],
stateOverrides: PartialState | undefined,
extras: Extras
) {
): Store {
let initialState;
if (stateOverrides) {
initialState = merge(
Expand All @@ -34,21 +45,17 @@ export default function (
return next(action);
};

const enhancer = compose(
applyMiddleware(
...[
thunk.withExtraArgument(extras),
mediaMiddleware(media),
emitterMiddleware,
...customMiddlewares,
].filter(Boolean)
)
);
const middlewares: Middleware[] = [
thunk.withExtraArgument(extras),
mediaMiddleware(media),
emitterMiddleware,
...customMiddlewares,
];

// The Redux types are a bit confused, and don't realize that passing an
// undefined initialState is allowed.
const store = initialState
? createStore(reducer, initialState, enhancer)
: createStore(reducer, enhancer);
return store;
// @ts-expect-error Typing of these is too hard to get right, so we cheat
const coercedMiddlewares: ReduxMiddleware[] = middlewares;

const enhancer = compose(applyMiddleware(...coercedMiddlewares));

return createStore(reducer, initialState, enhancer);
}

0 comments on commit 319f131

Please sign in to comment.