vuex-ts-decorators-fork-7
v0.0.14
Published
TypeScript decorators for working with Vuex, Initial Copyright - Casey Corcoran
Downloads
5
Readme
⚠️ This project is currently undergoing refactoring and is NOT production ready ⚠️
TypeScript Decorators for Vuex
Write Vuex stores and modules with type-safety and code completion
Primer
While working with decorators in TypeScript, it helps to have a basic understanding of what they are (and aren't) doing. With these decorators we'll write classes which are transformed into Vuex module/store definitions. It's important to note that we will never use new
or extend
with the decoratated classes.
Utilizing class
allows for a straightforward and ergonomic syntax while also providing usable typings down the line. When we combine that benefit with the added convenience of a normalized scope for our actions, mutations and getters (provided by the decorators) we end up with less boilerplate, strict-typing and clearer code across the board.
Basic example
The following snippet shows a standard Vuex declaration followed by an example using decorators.
Without Decorators:
const MyStore = new Vuex.Store({
state: {
prop: 'value'
},
getters: {
['myStore/myGetter'](state, getters) {
return state.prop + ' gotten';
},
['myStore/myOtherGetter'](state, getters) {
return getters.myGetter + ' again';
}
},
actions: {
['myStore/myAction']({commit, getters}, payload) {
commit('myStore/myMutation', getters.['myStore/myOtherGetter'] + payload.prop);
}
},
mutations: {
['myStore/myMutation'](state, payload) {
state.prop = payload;
}
}
})
With Decorators:
@module()
class MyStore {
prop = 'value';
@getter('myStore/myGetter')
get myGetter(): string {
return this.prop + ' gotten';
}
@getter('myStore/myOtherGetter')
get myOtherGetter(): string {
return this.myGetter + ' again';
}
@action('myStore/myAction')
private myAction(payload: string): Promise<void> {
this.myMutation(this.myOtherGetter + payload.prop);
}
@mutation('myStore/myMutation')
private myMutation(payload: string) {
this.prop = payload;
}
}
Typing your stores and modules
It's important to note that by themselves, these decorators do not provide full type-safety. Instead they allow us to write our stores and modules in a way that allows us to achieve type-safety via normal TypeScript conventions.
Declaring actions, getters and mutations
Leveraging TypeScript's “declaration merging” we can easily specify our store's api to achieve type-safety and code-completion throughout our application.
In order to define our api, we first import a few constants and declare our module/store's api:
// myStore.ts
import {Actions, Getters, Mutations, Promises, Store} from 'vuex-ts-decorators/constants';
declare module 'vuex-ts-decorators/constants' {
// name: payload type
interface Actions {
'myStore/myAction': string;
}
// name: promise type *required*
interface Promises {
'myStore/myAction': void;
}
// name: payload type
interface Mutations {
'myStore/myMutation': string;
}
// name: type
interface Getters {
'myStore/myGetter': string,
'myStore/myOtherGetter': string
}
}
Example usage and code structure
For futher answers and information, please check out the companion vuex-ts-example project. You'll be able to see the decorators in action as well as some guidance on how you can structure your code for the best results.