Skip to content

Instantly share code, notes, and snippets.

@merlosy
Created March 23, 2022 21:25
Show Gist options
  • Save merlosy/16d5251edf082d2f3cfa599ef8c1733f to your computer and use it in GitHub Desktop.
Save merlosy/16d5251edf082d2f3cfa599ef8c1733f to your computer and use it in GitHub Desktop.
Vuex class types
/**
Usage:
@Action(nameOf<ActionFn>('myAction'), { namespace: 'my-module'})
loadGraph!: ActionType<'myAction'>;
*/
function _createActions() {
return {
/** Action to load a new graph */
async myAction({ commit }: { commit: Commit }, payload: MyActionPayload): Promise<void> {
commit(MyMutationEnum.USE_CASE, payload);
},
... // other actions
};
}
export const createActions = _createActions as () => ActionTree<CanvasState, unknown>;
/** Internal prototype of the action */
export type ActionFn = ReturnType<typeof _createActions>;
/** Action names for Module */
export type ActionName = keyof ActionFn;
/** Action payload for a given action */
export type ActionPayload<A extends ActionName> = Parameters<ActionFn[A]>[1];
/** Prototype of the Module action */
export type ActionType<A extends ActionName> = ActionPayload<A> extends undefined ?
() => Promise<void>
: (payload: ActionPayload<A>) => Promise<void>;
/**
Usage:
@Getter(nameOf<GetterFn>('isLoading'), { namespace: 'my-module'})
isThingLoading!: GetterType<'isLoading'>;
*/
const _getters = {
/**
* Get whether it's loading
* @param state The current state
*/
isLoading(state: MyState): boolean {
return state.isLoading;
},
// other getters
}
export const getters = _getters as GetterTree<MyState, unknown>;
/** Getters function types for the module */
export type GetterFn = typeof _getters;
/** Getters names for this module */
export type GetterName = keyof GetterFn;
/** Getter return types for the current module */
export type GetterType<G extends GetterName> = ReturnType<GetterFn[G]> extends (...args: infer Params) => infer Return ?
(...args: Params) => Readonly<Return>
: Readonly<ReturnType<GetterFn[G]>>;
const _mutations = {
[MyMutationEnum.USE_CASE](state: MyState, payload: MyPayload): void {
// Do things
}
// other mutations
};
export const mutations = _mutations as MutationTree<MyState>;
type Mutations = typeof _mutations;
/** Name of the mutations */
export type MutationName = keyof Mutations;
/** Mutation payload for a given mutation */
export type MutationPayload<M extends MutationName> = Parameters<Mutations[M]>[1];
/** Mutation function types */
export type MutationFn<M extends MutationName> = Mutations[M];
type valueOf<T> = T[keyof T];
/**
* Gets the name of a class or an object property
* @param name the property name
*/
export function nameOf<T>(name: keyof T): keyof T;
/**
* Gets the name of a class or an object property
* @param func the lambda used to get the property
*/
export function nameOf<T>(func: (x: T) => unknown): valueOf<{ [K in keyof T]: T[K] extends unknown ? K : never }>;
export function nameOf<T>(func: ((x: T) => unknown) | keyof T): keyof T {
if(typeof func === 'function') {
const proxy = new Proxy({}, {
get: (target, key) => key
});
return func(proxy as T) as keyof T;
}
return func;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment