Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Vuex 4 modules in Vue 3 with TypeScript, and how to fix cyclical dependency linting error?

Tags:

As of this writing, Vue 3.0 has reached it's first stable v3.0.0 'One Piece' release, with Vuex 4 being in v4.0.0-beta.4.

Unfortunately there is no official examples yet on how to use Vuex 4 modules in TypeScript...

As a further requirement, I want to have store modules state, mutations, getters, and actions in their own files. This makes it easier to manage the code when these modules grow.

I managed to piece together a working example repository in Github and Codesandbox.

By using the examples provided in these resources:

  • Vuex + TypeScript by Andrew in Dev.to
  • Gist javisperez/index.ts
  • Repo andrewvasilchuk/vuex-typescript
  • Vue 3 & Vuex 4: useStoreModule composable by Barylski in Dev.to
  • A complete guide to mapping in Vuex by LogRocket

However, a few quirks remains to be solved:

1. Resolving dependency cycle linting errors

Currently the typings in a module's index.ts, actions.ts, and getters.ts are dependent on importing RootState from the main store.

When using ESLint Airbnb linting config, I'm barraged with linting errors like (currently disabled by // eslint-disable-next-line rules in the repo and example):

Dependency cycle via @/store/modules/profile > eslint(import/no-cycle)

While this doesn't seem to affect the actual functioning of the store (or does it?), I'd like to know how to overcome this without needing to turn the rule off, or needing to use // eslint-disable-next-line import/no-cycle on those lines?

I haven't tried if this happens with Standard and Prettier linter configs, or is it related to Airbnb rules?

2. How to have a module without any actions?

I tried to have profile module configured without using any actions, however I was unable to get the types rights.

Currently the example code includes one NON_ACTION action type...

3. How to correctly use namespaced: true module option, and how it affects the usage syntax in components?

Currently profile store is configured with namespaced: true. In the App.vue I'm demonstrating it by using mapGetters, which takes a module name as the first parameter. This works.

However, documents module is without this option, because dispatch with the action type doesn't work anymore. It seems to be needing to be used with some other syntax variant which I was unable to find.

PS. Any further code polishing suggestion are much welcome as comments, answers, and pull requests!

Update 27/09/20: I just realized VS Code intellisense is not showing type information for the store instance after passing it from useStore function, when used inside component. Works if imported in .ts file.

like image 351
ux.engineer Avatar asked Sep 26 '20 17:09

ux.engineer


1 Answers

I have published a package to help with using Vuex 4 with Typescript. It's not perfect, but it covers 95% of the issues we had. Any feedback would be appreciated.

It requires TS 4.1+ for the template literal support.

https://www.npmjs.com/package/typed-vuex-wrapper

FWIW the initial implementation was highly inspired by your start on modules, but expands that, and supports mapState/mapActions, etc with fully typed access. Requires TS 4.1 for the template literal support to allow fully safe namespaced access without magic strings.

like image 111
Tim Avatar answered Sep 20 '22 20:09

Tim