Skip to content

Instantly share code, notes, and snippets.

@doorgan
Last active March 14, 2021 03:00
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save doorgan/96e75b1d4ddd7cf35e9fbc9dce3c6240 to your computer and use it in GitHub Desktop.
Save doorgan/96e75b1d4ddd7cf35e9fbc9dce3c6240 to your computer and use it in GitHub Desktop.
Typed vuex mapState
import { mapState as originalMapState } from "vuex";
// Utilities to map the record fields to their function return types
// See https://github.com/microsoft/TypeScript/issues/15763#issuecomment-364205392
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
type MappedOutputs<T> = {
[P in keyof T]: () => ReturnType<T[P]>; // This is a lambda so it fulfills vuex's contract
};
type MapperRecord<S> = Record<string, (store: S) => any>;
type Expand<T> = {} & { [P in keyof T]: T[P] };
interface MapperWithNamespace<S> {
(map: (keyof S)[]): { [K in keyof S]?: () => S[K] };
(namespace: string, map: (keyof S)[]): { [K in keyof S]?: () => S[K] };
<T extends MapperRecord<S>>(record: T): Expand<MappedOutputs<T>>;
}
export const mapState = originalMapState as MapperWithNamespace<iState>;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment