Mikkel J
Mikkel J

Reputation: 3

Typing of Redux custom observeStore-function

I am trying to convert a Redux-implementation to Typescript, but are having difficulties making our observeStore Utility-function typesafe.

This is the original function:

function observeStore(store, select, onChange) {
  let currentState;

  function handleChange() {
    let nextState = select(store.getState());
    if (nextState !== currentState) {
      currentState = nextState;
      onChange(currentState);
    }
  }

  let unsubscribe = store.subscribe(handleChange);
  handleChange();
  return unsubscribe;
}

I have unsuccessfully tried something like this:

function observeStore(store: RootState, select: (RootState) => PartOf???<RootState>, onChange: (ReturnType<typeof select>) => void): Unsubscribe

Upvotes: 0

Views: 191

Answers (1)

Linda Paiste
Linda Paiste

Reputation: 42228

The types depend on the type of the selected value, so you need to use a generic function. I am assuming based on your try that RootState is a known value, so the only generic that we need is for the selector's return type.

  • store is the entire store (not the state) so we use the Store type imported from redux with the state generic set to RootState
  • select is a function that selects something from the state, so it takes RootState and returns T
  • onChange is a function that takes the selected value T and returns void
  • currentState is the selected value T, but it is initially undefined.
import {Store, Unsubscribe} from "redux";

function observeStore<T>(
  store: Store<RootState>,
  select: (state: RootState) => T,
  onChange: (selected: T) => void
): Unsubscribe {

  let currentState: T | undefined;

  function handleChange() {
    let nextState = select(store.getState());
    if (nextState !== currentState) {
      currentState = nextState;
      onChange(currentState);
    }
  }

  let unsubscribe = store.subscribe(handleChange);
  handleChange();
  return unsubscribe;
}

Typescript Playground Link

Upvotes: 2

Related Questions