#Figuring out Type for Reselect/Selector call

2 messages · Page 1 of 1 (latest)

carmine yacht
#

Howdy,

Inherited a project that hasn't been updated in a while. Tests pass and I managed to rectify all but 1 typescript issue.
It obviously goes away if I cheat with any but I want to learn the right way.

I've narrowed it down to the change to Reselect in v4.1.3+ https://github.com/reduxjs/reselect/releases/tag/v4.1.3

**It also wouldn't surprise me if my project itself had bad practices **

Error:
`src/hooks/use-selector.ts:13:22 - error TS2345: Argument of type '(state: import("/Users/jjH/Projects/product-configurator/product-configurator/node_modules/@reduxjs/toolkit/node_modules/reselect/es/types").Head<import("/Users/jjH/Projects/product-configurator/product-configurator/node_modules/@reduxjs/toolkit/node_modules/reselect/es/versionedTypes/ts47-mergeParameters").MergePar...' is not assignable to parameter of type '(state: import("/Users/jjH/Projects/product-configurator/product-configurator/node_modules/@reduxjs/toolkit/node_modules/reselect/es/types").Head<import("/Users/jjH/Projects/product-configurator/product-configurator/node_modules/@reduxjs/toolkit/node_modules/reselect/es/versionedTypes/ts47-mergeParameters").MergePar...'.
  Types of parameters 'state' and 'state' are incompatible.
   
.... 
      Source has 1 element(s) but target requires 2.

** return useSelector(createStructuredSelector(selectors), shallowEqual);**

#

More files:

Looks like my original devs use Reselect when they want to combine memoized Selectors, and Redux' built in when its a Single.

src/hooks/use-selector.ts

import { createStructuredSelector, Selector } from "reselect";

import { RootState } from "root-reducer";

export function useSingleSelector(selector: Selector<RootState, any>): any {
  return useSelector(selector, shallowEqual);
}

export function useStructuredSelector<T>(selectors: {
  [K in keyof T]: Selector<RootState, T[K]>;
}): any {
  return useSelector(createStructuredSelector(selectors), shallowEqual);
}

src/root-reducer.ts


import cart from "slices/cart";
import configuration from "slices/configuration";
import session from "slices/session";
import theme from "slices/theme";
import build from "slices/build";
import valve from "slices/valve";
import viewer from "slices/viewer";

const rootReducer = combineReducers({ cart, configuration, session, theme, build, valve, viewer });

export type RootState = ReturnType<typeof rootReducer>;

export default rootReducer;

src/store.ts

import { configureStore } from "@reduxjs/toolkit";

import rootReducer from "./root-reducer";

const store = configureStore({
  reducer: rootReducer,
});

// Cannot mock module.hot without ejecting the app
/* istanbul ignore if */
if (process.env.NODE_ENV === "development" && module.hot) {
  module.hot.accept("./root-reducer", () => {
    // eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
    const newRootReducer = require("./root-reducer").default;
    store.replaceReducer(newRootReducer);
  });
}

export type AppDispatch = typeof store.dispatch;

export default store;