Start by adding a new plugin.ts file. A plugin is just a function that takes the store as a parameter. In order to type it, we need to import store from Vuex, and it needs the root state as a parameter, because it's a generic. Let's import it as well.
Then type it as a store root state. Having the store instance, we can subscribe to every motation it triggers. Subscribe takes motation and a state as parameters. The parameter types should be inferred from the store root state that we have indicated above.
If in the Vuex version you are using, you don't see motation typed as a motation payload, then you can create a payload interface yourself with a type as a string and a payload as any, and then use that type there, but whether keep up to date with the latest versions.
This history plugin will add a for history state all the motations that have been called. For that, let's commit a motation called history/add that we will implement, and pass the motation as the payload. A point here is, since we are subscribing to every motation that is called, and in there, we calling a motation, that will end up in an endless loop.
To solve that, let's check that the type of the motation is not history add. Then wrap the store commit inside that condition. Let's add here a console log as well in order to quickly check it in the console.
Now, let's implement a history module. It will have a state with a history array, and an add motation that takes the state and the motation as parameters. In there, we'll push the motation to the state.history. Let's indicate as well namespace true for better isolation.
Now, let's type the module. First, import module from Vuex, and type it with the module type, which is a generic that takes the module state as the first parameter -- in this case, history state that we are going to implement -- and as the second, the root state, and import the history state.
Then go to the types file, and let's write here the history state. It's going to have an array of motation payloads that we have to import from Vuex. Then replace the to-do type by a motation payload, and the to-dos property by history.
Now, go back to the plugin, and whoa, we see there is a typo in the state.history. This is the power of TypeScript, that as soon as you start adding types, errors will start to appear. At this point, we can already register the module by using the register module function from the store, just when the plugin gets loaded.
Finally, we only have to import it, history from plugin, and add it to the Vuex store using a plugins property, which is an array of plugins. Now, if we try this out, let's run a couple of motations. Then if we check in the state, let's make this a bit wider. We'll see there the history property with those two motations that we just ran.