Skip to content

Instantly share code, notes, and snippets.

@rjdestigter
Last active September 21, 2018 19:11
Show Gist options
  • Save rjdestigter/4caf7070a699f3e4c3bf6645f018f333 to your computer and use it in GitHub Desktop.
Save rjdestigter/4caf7070a699f3e4c3bf6645f018f333 to your computer and use it in GitHub Desktop.
A type safe function that takes a map of state selectors and returns, - a function that takes state and returns, - a map with the same keys and the result of the selectors.
/**
* @private
*
* An object representing a map of selector functions that
* accept application state and return a value.
*/
interface MapOfSelectors {
[prop: string]: (storeState: any) => any
}
/**
* @private
*
* Returns a type representing a map of values based on a map of state selectors and the values those state selectors return
*/
type MapOfPropsFromMapOfSelectors<T extends any> = {
[P in keyof T]: T[P] extends (storeState: any) => infer B ? B : T[P]
}
/**
* @private
*
* Describes a `"mapStateoProps"` function composed using a map (object) of selector functions
*/
type MSTP<T> = (storeState: any) => MapOfPropsFromMapOfSelectors<T>
/**
* Helper function for creating `mapStateToProps` functions.
*
* Takes a map of selector functions, for example:
*
* ```typescript
* const mapOfSelectors = {
* counter: (storeState: any): number => state.counter.value,
* user: (storeState: any): User[] => state.users
* }
* ```
*
* and returns a function that takes `state` and returns an object
* with the same keys and the results of those selectors:
*
* ```typescript
* (storeState: any) => {
* return {
* counter: 4,
* user: [{id: 4, username: "Bob"}],
* }
* }
*/
export default <T extends MapOfSelectors>(mapOfSelectors: T): MSTP<T> => (
storeState: any
): MapOfPropsFromMapOfSelectors<T> =>
Object.keys(mapOfSelectors).reduce((acc, key) => {
const thunk = mapOfSelectors[key]
acc[key] = thunk(storeState)
return acc
}, Object.create(null))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment