ktsn / vuex-type-helper Goto Github PK
View Code? Open in Web Editor NEWType level helper to ensure type safety in Vuex
Type level helper to ensure type safety in Vuex
I'm working on Clean Architecture Boilerplate for Vue App. And for now Im challenging an issue with Store Abstraction. I've found out that there is a FluxStandardAction package which is standard
declaration interface of actions in flux stores. I wannted to use this in my Vuex Store declaration and got some issues with this.
For now I have something like that:
// types/actions.ts
export enum ActionTypes {
TOGGLE_SIDEBAR = "toggleSidebar"
}
export type toggleSidebarPayload = {
toggled: boolean;
}
export interface toggleSidebarInterface extends FluxStandardAction<toggleSidebarPayload>{
type: ActionTypes.TOGGLE_SIDEBAR;
}
export class toggleSidebar implements toggleSidebarInterface {
public type = ActionTypes.TOGGLE_SIDEBAR;
constructor(public payload: toggleSidebarPayload) {}
}
//types/index.ts
export interface SidebarState {
toggled: boolean
}
export interface SidebarGetters {}
export interface SidebarActions {
[ActionTypes.TOGGLE_SIDEBAR]: toggleSidebarPayload
}
export interface SidebarMutations {
[MutationTypes.TOGGLE_SIDEBAR]: toggleSidebarPayload
}
//sidebar/actions.ts
export const actions: DefineActions<SidebarActions, SidebarState, SidebarMutations, SidebarGetters> = {
[ActionTypes.TOGGLE_SIDEBAR]({ commit }, {toggled} : toggleSidebarPayload) {
commit(MutationTypes.TOGGLE_SIDEBAR, {toggled})
}
};
My StoreGateway implementation is something like that:
export default abstract class StoreGateway {
abstract store;
abstract namespace;
dispatch(action: FluxStandardAction<any>): any {
return this.store.dispatch({
type: this.namespace + '/' + action.type,
...(action.payload) ? action.payload : {}
})
}
...
My SidebarRepository is like:
toggleSidebar(action: toggleSidebarInterface) {
return this.sidebarStoreGateway.dispatch(action);
}
And then I can call this gateway in repository with the instance of flux action class:
this.sidebarRespository.toggleSidebar(new toggleSidebar({toggled:true}));
And my actually question is that, is there any better way to definee my actions in store with use of FluxStandardActionInterface.
So to create actions from FluxStandardActionInterfaces or anything like that?
When using the NPM version (which is three commits behind master), the helpers.d.ts
contains a require()
-style import.
In my setup this prevents the compilation. When I change it to an ES6-style import, as it is on master, it compiles.
Would it be possible to update the NPM package?
(By the way, I really love how straight forward this helper is to use!)
When I define a mutation like this
export interface User {
id: number;
}
export interface AuthState {
currentUser: User | null;
}
export interface AuthMutations {
unsetCurrentUser: undefined;
}
const mutations: DefineMutations<AuthMutations, AuthState> = {
unsetCurrentUser(state) {
state.currentUser = null;
}
}
Now, when I call the unsetCurrentUser
mutation, I need to explicitly pass undefined
. Is that necessary?
mutations.unsetCurrentUser(state, undefined) // passes
mutations.unsetCurrentUser(state) // fails
I'm using typescript 3.1.6 and I'm getting this compile error:
node_modules/vuex-type-helper/helpers.d.ts:20:99 - error TS2536: Type 'Map[K]' cannot be used to index type 'T'.
20 <Key extends keyof T, Map extends Record<string, Key>>(map: Map): { [K in keyof Map]: (payload: T[Map[K]]) => R }
~~~~~~~~~
With a store defined like below
const store = new Vuex.Store({
modules: {
table: tableReducer
}
})
tableReducer: {
namespaced: true,
state,
getters,
mutations,
actions
}
and Actions typed like below
export interface TableActions {
fetchMetadata: any,
fetchData: any
}
I get a typings error in my view when i want to dispatch an action like this
await this.$store.dispatch<Dispatcher<TableActions>>({
type: 'table/fetchMetadata'
})
However when I change the type to
await this.$store.dispatch<Dispatcher<TableActions>>({
type: 'fetchMetadata'
})
there are no typings error anymore but the action is not dispatch
Current solution right now is
await this.$store.dispatch<Dispatcher<any>>({
type: 'table/fetchMetadata'
})
Is there a better solution ?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.