JavaScript でも Vuex 定義時に推論をしたい
TypeScript の場合は Vuex and Typescript - codeburst などをさんこうにしましょう
JavaScript で TypeScript のような推論を行う事例として
- 上記の Vuex and Typescript と
- Type Safe JavaScript with JSDoc - TruckJS - Medium との組み合わせにておこないます
モジュールモードですぐに Vuex の store が使用できる Nuxt.js にてやります
state の定義
Vuex and Typescript では ProfileState
, RootState
をそれぞれ定義しています。
Vuex の Getter や Action が <S, R>
などとしてもとめているからです
RootState にあたるもの
「中身」の State
も export
対象にしているところがポイントです
Vuex and Typescript にて定義されている interface RootState
の代わりとかんがえてください
State
と state
でわかりずらいかもしれないのでこの変数定義はあんまりよくないかもしれません
export const State = {
'ba-john': 'ichi'
}
export const state = () => Object.assign({}, State)
ProfileState と同じ位置づけのもの
モジュールモードなので export default
で定義したら勝手にモジュールになります
こっちも State
を定義して export
対象としています
/**
* @typedef {Object} State
* @property {string} namae なまえ
*/
/** @type {State} */
export const State = {
namae: 'ichi'
}
export default () => Object.assign({}, State)
getters 定義
getters の定義の際には Vuex より Getter
を import
しましょう
さらに state で定義しておいたそれぞれの State
をそれぞれ import
して
getter として定義する変数に JSDoc にて @type
を指定します。
下記の例は State
をそれぞれ Root
と Local
として別名にしています
/**
* @typedef {import('@/store').State} RootState
* @typedef {import('./state').State} State
*/
/** @type {import('vuex').GetterTree<State, RootState>} */
const getters = {
getNamae: (state) => state.namae,
}
export default getters
にょきにょき生えてくる state の中身
このようにして actions や mutations にも Vuex の Action<S,R>
Mutation<S>
に
適切な state のオブジェクトを指定することで推論がきくようになります
mutations 定義
つごうにより actions の前に mutations を定義します
/**
* @typedef {import('./state').State} State
*/
// Mutation は state, payload が明示されればよく、
// また、 MutationTree を指定してしまうと mutations のプロパティが推論できなくなるようなので
// MutationTree を指定するメリットが現状少なそう
///** @type {import('vuex').MutationTree<State>} */
const mutations = {
/**
* @param {State} state
* @param {{ namae: string }} payload
*/
setNamae: (state, payload) => {
state.namae = payload.namae
},
}
export default mutations
actions 定義
他と同様 Vuex の Action の定義の仕方に従って actions.js
を定義していますが・・・
同僚の mutations
もインポートしています
これは mutations の定義を流用してその推論により commit
をする際の参考にしております
(これは是非があるでしょうが・・・)
/**
* @typedef {import('@/store').State} RootState
* @typedef {import('./state').State} State
*/
/** @type {import('vuex').ActionTree<State, RootState>} */
const actions = {
/**
* @param {{ namae: string }} payload
*/
setNamae: (context, payload) => {
// 定義名を利用して commit を実施
context.commit(mutations.setNamae.name, payload)
},
}
export default actions
Action での context
にはいろいろと格納されているので
推論で中身がみれたほうが便利と思われます