Skip to content

Instantly share code, notes, and snippets.

@flushentitypacket
Last active August 30, 2018 22:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save flushentitypacket/c41e8f29887f713fb5694e76e96731a4 to your computer and use it in GitHub Desktop.
Save flushentitypacket/c41e8f29887f713fb5694e76e96731a4 to your computer and use it in GitHub Desktop.
Typescript Redux selector wrapper, useful for keeping selector logic within its own state module
type Selector<State, R = any> = (state: State) => R
// TODO:
// Preferred call signature:
// ```
// wrapSelector<S>(fn, key)
// ```
// But currently not possible due to "all-or-nothing" type arguments:
// https://github.com/Microsoft/TypeScript/issues/10571
export const wrapSelector = <S, SS extends Selector<S[keyof S]>>(
selector: SS,
key: keyof S,
) => {
return (s: S) => selector(s[key])
}
export const wrapSelectors = <S, SS extends {[k: string]: Selector<S[keyof S]>}>(selectors: SS, key: keyof S) => {
return Object.keys(selectors).reduce<{[P in keyof typeof selectors]: Selector<S, ReturnType<(typeof selectors)[P]>>}>((wrappedSelectors: any, skey) => {
const selector = selectors[skey]
const wrappedSelector = wrapSelector<S, typeof selector>(selector, key)
return {
...wrappedSelectors,
[skey]: wrappedSelector,
}
}, {} as any)
}
export type State = {
harry: string,
}
const selectHarry = (s: State) => s.harry
export const selectors = {
selectHarry,
}
import {State as HogwartsState, selectors as hogwartsSelectors} from './hogwarts'
import {wrapSelectors} from './_wrapSelector'
type State = {
hoggos: HogwartsState,
}
const selectors = {
...wrapSelectors(hogwartsSelectors, 'hoggos'),
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment