Vuex-moduler med TypeScript
REDIGERA:
Sedan Vue-konferensen i Toronto (sent 2021) har Vue officiellt gått över till Pinia för TypeScript-stöd, istället för Vuex. De medger också att Vuex var ökänd för att vara svår att arbeta med när man försökte använda TypeScript och dela upp ett store i flera moduler, samtidigt som man behöll de flesta fördelarna med TypeScript. Därför är denna fråga inte längre relevant.
Originalinlägg:
Jag försöker skapa en statiskt typad Vuex-store med flera moduler. Jag har läst flera artiklar, men måste erkänna att jag sitter fast, vilket är anledningen till att jag hoppas att någon här kan hjälpa mig. Jag har för närvarande 2 moduler; documentation och workAgreement, med starkt typade commit- och dispatch-metoder i ..store/modules/{module}/types.ts.
export type AugmentedWorkAgreementContext = {
commit: WorkAgreementStore["commit"],
dispatch: WorkAgreementStore["dispatch"]
} & Omit < ActionContext < IWorkAgreementState, RootState > , 'commit' | "dispatch" >
export type WorkAgreementStore < S = IWorkAgreementState > = Omit < Store < S > , "commit" | "getters" | "dispatch" >
&
{
commit < K extends keyof IWorkAgreementMutations,
P extends Parameters < IWorkAgreementMutations[K] > [1] > (
key: K,
payload: P,
options ? : CommitOptions
): ReturnType < IWorkAgreementMutations[K] > ;
} & {
dispatch < K extends keyof IWorkAgreementActions,
P extends Parameters < IWorkAgreementActions[K] > [1] > (
key: K,
payload: P,
options ? : DispatchOptions
): ReturnType < IWorkAgreementActions[K] > ;
} & {
getters: {
[K in keyof IWorkAgreementGetters]: ReturnType < IWorkAgreementGetters[K] >
}
}Detta görs sedan om till en typ i ..store/index.ts med följande kod.
export type RootState = {
workAgreement: IWorkAgreementState
documentation: IDocumentationState
}
export const store = createStore({
modules: {
documentationStore,
workAgreementStore,
}
})
type Store = DocumentationStore < Pick < RootState, 'documentation' >> & WorkAgreementStore < Pick < RootState, 'workAgreement' >>
export function useStore(): Store {
return store as Store
}Härifrån försöker jag använda det i en komponent, och det fungerar till viss del, mitt problem är att det inte hjälper mig med intellisense på en av modulerna, specifikt vilken som helst som är den sista på
typ Store=DocumentationStore<Pick<RootState, 'documentation'>> & WorkAgreementStore<Pick<RootState, 'workAgreement'>>
Koden inom komponenten låter mig använda de tillgängliga hämtarna från båda med autokomplettering, så jag är lite förvirrad över vad jag gör fel. Det ser ut som att jag har två överlagringar, men den andra ser ganska dålig ut. Här är koden i komponenten som referens och bilder på problemet jag har.
import {
defineComponent
} from 'vue'
import {
useStore
} from "@/store";
import {
computed
} from "vue";
export default defineComponent({
data() {
return {
store: useStore()
}
},
setup() {
const store = useStore()
const thisIsATest = computed(
() => store.getters.GetAnotherDocumentation
)
},
yetAnotherTest() {
this.store.commit()
}
})
`enter code here`Den med intellisense
Den utan intellisense