We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
vuex.ts Template Literal Types Help class, no intrusion config
import { CommitOptions, DispatchOptions, Store as VuexStore, useStore as vuexUseStore, createStore as vuexCreateStore, StoreOptions as VuexStoreOptions, ActionContext as VuexActionContext, } from 'vuex'; export type LiteralType<Prefix, Keys> = `${Prefix & string}/${keyof Keys & string}`; //modules first level node export type GetMutations<T> = T extends { mutations: infer V } ? V : never; export type GetActions<T> = T extends { actions: infer V } ? V : never; export type GetGetters<T> = T extends { getters: infer V } ? V : never; export type GetModules<T> = T extends { modules: infer V } ? V : never; export type GetState<T> = T extends { state: infer V } ? V : never; //mutations subModules child node export type SubModuleMutationsKeys<Module, Key> = Module extends { modules: infer SubModules; } ? LiteralType<Key, ModulesMutationsKeys<SubModules>> : never; export type ModuleMutationsKeys<Module, Key> = | LiteralType<Key, GetMutations<Module>> | SubModuleMutationsKeys<Module, Key>; export type ModulesMutationsKeys<Modules> = { [K in keyof Modules]: ModuleMutationsKeys<Modules[K], K>; }[keyof Modules]; //actions subModules child node export type SubModuleActionsKeys<Module, Key> = Module extends { modules: infer SubModules; } ? LiteralType<Key, ModulesActionsKeys<SubModules>> : never; export type ModuleActionsKeys<Module, Key> = | LiteralType<Key, GetActions<Module>> | SubModuleActionsKeys<Module, Key>; export type ModulesActionsKeys<Modules> = { [K in keyof Modules]: ModuleActionsKeys<Modules[K], K>; }[keyof Modules]; //getters subModules child node export type SubModuleGettersKeys<Module, Key> = Module extends { modules: infer SubModules; } ? LiteralType<Key, ModulesGettersKeys<SubModules>> : never; export type ModuleGettersKeys<Module, Key> = | LiteralType<Key, GetGetters<Module>> | SubModuleGettersKeys<Module, Key>; export type ModulesGettersKeys<Modules> = { [K in keyof Modules]: ModuleGettersKeys<Modules[K], K>; }[keyof Modules]; //state subModules child node export type SubModuleState<Module> = Module extends { modules: infer SubModules; } ? ModulesState<SubModules> : never; export type ModuleState<Module> = GetState<Module> | SubModuleState<Module>; export type ModulesState<Modules> = { [K in keyof Modules]: ModuleState<Modules[K]>; }; //get Keys export type Commit<Mutations, Modules> = | keyof Mutations | ModulesMutationsKeys<Modules>; export type Dispatch<Actions, Modules> = | keyof Actions | ModulesActionsKeys<Modules>; export type Getter<G, Modules> = keyof G | ModulesGettersKeys<Modules>; type RootState<T> = T extends unknown ? Record<string, unknown> : T; export type States<State, Modules> = RootState<State> & ModulesState<Modules>; interface LiteralStore<State, Mutations, Actions, Getters, Modules> extends Omit< VuexStoreOptions<any>, 'state' | 'getters' | 'mutations' | 'actions' | 'modules' > { state?: State; getters?: Getters; mutations?: Mutations; actions?: Actions; modules?: Modules; } export interface StoreOptions< S = unknown, Mutations = unknown, Actions = unknown, Getters = unknown, Modules = unknown, > extends LiteralStore<S, Mutations, Actions, Getters, Modules> {} interface Store<S, Mutations, Actions, Getters, Modules> extends LiteralStore<S, Mutations, Actions, Getters, Modules>, Omit<VuexStore<any>, 'state' | 'getters'> {} export function createStore<S, Mutations, Actions, Getters, Modules>( options: StoreOptions<S, Mutations, Actions, Getters, Modules>, ): Store<S, Mutations, Actions, Getters, Modules> { return vuexCreateStore(<VuexStoreOptions<any>>options); } export class UseStore<S extends StoreOptions> { private readonly store: VuexStore<any>; readonly state: States<GetState<Required<S>>, GetModules<Required<S>>>; readonly getters: Record< Getter<GetGetters<Required<S>>, GetModules<Required<S>>>, any >; constructor() { this.store = vuexUseStore(); this.state = this.store.state; this.getters = this.store.getters; } commit<P = any>( type: Commit<GetMutations<Required<S>>, GetModules<Required<S>>>, payload?: P, options?: CommitOptions, ) { this.store.commit(type as string, payload, options); } async dispatch<P = any>( type: Dispatch<GetActions<Required<S>>, GetModules<Required<S>>>, payload?: P, options?: DispatchOptions, ) { await this.store.dispatch(type as string, payload, options); } } export function useStore<Vuex>() { return new UseStore<Vuex>(); } export interface ActionContext<T> extends Omit<VuexActionContext<any, any>, 'commit'> { commit<P = any>(type: keyof T, payload?: P, options?: CommitOptions): void; }
demo.ts
import { ActionContext } from './vuex'; interface State { width: number; } const mutations = { screenWidth(state: State, width: number) { state.width = width; }, }; export default { namespaced: true, state: { width: 0, }, mutations, actions: { test({ commit }: ActionContext<typeof mutations>) { commit('screenWidth'); }, }, };
store.ts
import { createStore } from './vuex'; import demo from './demo'; const store = createStore({ state: { test:1 }, modules: { demo } }); export default store; export type Vuex = typeof store;
main.ts
import { createApp } from 'vue'; import vuex from './store'; import App from './App'; const app = createApp(App).use(vuex);
Use
import { defineComponent, watch } from 'vue'; import { useStore } from './vuex'; import { Vuex } from './store'; export default defineComponent({ name: 'App', setup() { const store = useStore<Vuex>(); const value = store.state.demo.width; store.commit('demo/screenWidth',Math.random().toFixed(3)); return () => { return ( <div> <button onClick={() => { store.commit('demo/screenWidth',Math.random().toFixed(6)); }}> test </button> </div> ); }; }, });
#1831 (comment)
The text was updated successfully, but these errors were encountered:
getters?
Sorry, something went wrong.
No branches or pull requests
What problem does this feature solve?
What does the proposed API look like?
vuex.ts
Template Literal Types Help class, no intrusion config
Example
demo.ts
store.ts
main.ts
Use
#1831 (comment)
The text was updated successfully, but these errors were encountered: