vuex4 提供了key来实现强类型,但需要开发者自己定义state类型,使用modules的时候会非常不便, 稍微研究了一下typescript的类型, 可以实现从多个modules中推导出root state的类型。
第一步:将所有store组织成modules
const modules = {
categories, //store a
plugins //store b
}
第二步:通过infer获取单个store的state的类型
note: 当类型 T 兼容 { state: infer S }
时,返回state的类型S
type StoreState<T> = T extends { state: infer S } ? S : T
// 原始类型为:{ state: { a, b... }
// StoreState<T>为: { a, b... }
第三步:替换modules的value的类型,重新组织成正确的类型
// 替换类型T的value的类型成StoreState
type ModulesState<T> = {
[key in keyof T]: StoreState<T[key]>
}
export type State = ModulesState<typeof modules>;
// 原始类型为: { categories: { state: { cateA, cateB ... };
// 新类型State为:{ categories: { cateA, cateB ... };
完整代码:
import { InjectionKey } from 'vue';
import { createStore, Store } from 'vuex'
import categories from "./categories"
import plugins from "./plugins"
const modules = {
categories,
plugins
}
type StoreState<T> = T extends { state: infer S } ? S : T
type ModulesState<T> = {
[key in keyof T]: StoreState<T[key]>
}
export type State = ModulesState<typeof modules>;
export const key: InjectionKey<Store<State>> = Symbol();
export default createStore<State>({
modules
})