I was working on a app that I wanted to do the same. For my needs, I just wanted a simple selector, so I did this:
// store.ts
// …omitted store configuration
export type RootState = ReturnType<typeof store.getState>;
// create a generic type called AppSelector
export type AppSelector<Return> = (state: RootState) => Return
// create a custom `createSelector` that uses the type above
export const createAppSelector = <R>(selector: AppSelector<R>): AppSelector<R> => selector
With the types above, we can do the following:
const selectTitle: AppSelector<string> = (state) => state.title;
// Note that using the AppSelector type requires you to always pass the return type argument
// It's much easier to use the createAppSelector function
// selectTitle and selectTitle2 accomplish the same thing
const selectTitle2 = createAppSelector((state) => state.title);
When inside createAppSelector
, state
will correctly have the RootState
type.
The limitation of this form is that, unlike createSelector
, createAppSelector
only allows you to create a single selector and doesn't allow you to combine or mutate the selections.
Hopefully someday we'll have a way to const createAppSelector: TypedCreateSelector<RootState> = createSelector;