How to use createSelector with parameter and Typescript?
Asked Answered
B

2

15

I use redux-toolkit to generate selectors. I want to use them in my own custom reselect selectors with parameters. But I do not know how to type the return type of my selector?

const selectOrganizationName = (id: string): ??? =>
  createSelector(
    [(state: RootState) => organizationSelectors.selectById(state, id)],
    organization => organization.name
  );

export default selectOrganizationName;
Missing return type on function.eslint@typescript-eslint/explicit-module-boundary-types
Bellona answered 9/3, 2021 at 18:57 Comment(0)
O
19

Keep in mind that this warning only appears due to your ESLint settings which require explicit return types. Typescript is able to infer the type properly.

When you call the selectOrganizationName function, you return a selector that takes a RootState and returns an organization name which is string | undefined.

type Return = (state: RootState) => string | undefined;

const selectOrganizationName = (id: string): Return =>
  createSelector(
    [(state: RootState) => organizationSelectors.selectById(state, id)],
    (organization) => organization?.name
  );

However you likely have lots of selectors that you want to create return types for, so you can create a helper type that includes your RootState automatically and just requires you to set the type of the selection.

type Selector<S> = (state: RootState) => S;

const selectOrganizationName = (id: string): Selector<string | undefined> =>
  createSelector(
    [(state: RootState) => organizationSelectors.selectById(state, id)],
    (organization) => organization?.name
  );

Typescript Playground Link

Overtrump answered 9/3, 2021 at 20:50 Comment(4)
This answer will result in select running every time component re-renders. For parameterized use-case make pattern is a better approach redux.js.org/recipes/computing-derived-dataTeakettle
What if my selector has arguments?Cushion
@Cushion if your selector has arguments then it breaks the rules of selectorsBeltz
What are the rules of selectors?Cushion
C
1

For me as soon as I added a selector for a custom param, it broke the TS of the entire file (all the selectors return types became any).

export const mappedFavouritesSelector = createSelector(
  // ...Other selectors...
  (_, hkSpotEnabled) => hkSpotEnabled,
  (
    // ...Other selector results...
    hkSpotEnabled,
  )

But the issue went away when I pulled out the param selector to a const function 🤷‍♂️:

const hkSpotEnabledSelector = (_: RootState, hkSpotEnabled: boolean) =>
  hkSpotEnabled;

export const mappedFavouritesSelector = createSelector(
  // ...Other selectors...
  hkSpotEnabledSelector,
  (
    // ...Other selector results...
    hkSpotEnabled,
  )
Coir answered 28/4, 2023 at 12:35 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.