Enhance your Vuex action types in Typescript by adding new actions or extending existing

I'm new to Typescript and I'm exploring ways to add specific type structure to all Actions declared in Vue store without repeating them in every Vuex module file.

For instance, instead of manually defining types for each action in every store file, it can be done as shown below:

// Global interface declaration.
interface ReturnObject {
   status: boolean;
   msg: string;
}

export default new Vuex.Store({
   actions: {
      // Each action needs to follow this pattern.
      exampleAction: async (context, payload): Promise<ReturnObject> => {
         return { status: true, msg: 'Hello World!' }
      },
   },
   modules: {
      // Also applied to actions in module files.
   }
})

However, the goal is to achieve the following approach:

export default new Vuex.Store({
   actions: {
      // Types are automatically inferred.
      async exampleAction(context, payload) {
         return {status: true, msg: 'Hello World!'}
      }
   },
   modules: {
      // Applied to actions in all module files.
   }
})

Answer №1

It is generally not recommended to modify original global behavior for specific local purposes. Instead of directly modifying it, a better approach would be to use custom helpers to extend the functionality. One possible solution is to create a simple wrapper that extends the original store types:

type CustomActionHandler<S, R> = (this: Store<R>, injectee: ActionContext<S, R>, payload?: any) => ReturnObject | Promise<ReturnObject>;

interface CustomActionTree<S, R> {
  [key: string]: CustomActionHandler;
}

interface CustomModule<S, R> extends Module<S, R> {
  actions?: CustomActionTree<S, R>;
}

export interface CustomModuleTree<R> {
  [key: string]: CustomModule<any, R>;
}

interface CustomStoreOptions<S> extends StoreOptions<S> {
  actions?: CustomActionTree<S, S>;
  modules?: CustomModuleTree<S>;
}

function createCustomStore<S>(options: CustomStoreOptions<S>) {
  return new Store(options);
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

`Running ng serve will result in the creation of a 'dist' folder within each app sub

Since beginning my project, I have encountered an issue that is both normal and frustrating. The dist folder is being created with incomplete information related to the components inside it. dashboard dist (unwanted) components panel dist (unwanted) c ...

Is it possible to assign default values to optional properties in JavaScript?

Here is an example to consider: interface Parameters { label: string; quantity?: number; } const defaultSettings = { label: 'Example', quantity: 10, }; function setup({ label, quantity }: Parameters = { ...defaultSettings }) { ...

Is it possible to host an SSR nuxt.js application on GitHub or GitLab pages?

Can you host a server-side rendering application using nuxt.js (universal ssr mode) with a Firebase backend on GitHub/Gitlab Pages? Gitlab provides an example at nuxt, and I'm curious if the server-side dynamic fetching still functions properly. ...

Utilizing component data in Vue.js to configure the router-link attribute

Is there a way to pass component data in <router-link to="...">? Here's an example: var data = { files: [{ name: "test", path: "/test" }] }; var component = { data: function() { return data; ...

Adjusting the height of a vertical slider in Vuetify2 is not customizable

I've been trying to adjust the height of a vertical slider in vuetify2, but setting it to "800px" or using style="height:800px" doesn't seem to work as intended. Even though the box within my grid expands, the height of the slider remains unchan ...

Issue regarding custom CSS implementation in Angular project

Being a French speaker, I apologize in advance for any mistakes I might make. I am also fairly new to Angular, so if you could provide detailed explanations in your responses, it would be greatly appreciated. Thank you. I am trying to import a custom CSS ...

Automatically trigger the expansion of all panels within Vuetify using code

I'm attempting to use Vuetify 2.3.5 to programmatically control the opening and closing of expansion panels. <v-expansion-panels accordion> <v-expansion-panel v-for="(item,i) in faqs" :key="i"> <div class ...

Exploring the interactive doughnut graph using SVG and Vue.js

Looking to create a unique dynamic donut chart using SVG and Vue. I want it to mirror the exact SVG format found on this webpage: (To see the animated chart, select a dish and click on ingredients) This might not have been the best approach, but it was ...

The use of '-' in v-bind:style within Vue.js

I'm having trouble figuring out how to use CSS code with dashes in v-bind:style. When I attempt something like this: <DIV style="width:100px;height: 100px;background-color: red;cursor: pointer;" v-bind:style="{ margin-left: margin + 'px' ...

Customizing form validation in React using Zod resolver for optional fields

I am currently working on creating a form using React-hook-form and zod resolver. My goal is to have all fields be optional, yet still required despite being marked as optional in the zod schema: const schema = z.object({ name: z.string().min(3).max(50 ...

Get access to environment variables dynamically using parameters

I'm currently developing a Vue plugin to retrieve the content of environment variables, similar to PHP's env() method. Background: I require a URL in multiple components and have stored it in the .env file anticipating potential future changes. H ...

What is the best way to increase padding in a Vuetify view element?

I have been attempting to increase the padding of my view by utilizing the "px-5" class on the container within the view. However, I am struggling to achieve the desired amount of padding. What I am aiming for is padding similar to what is shown in this sc ...

What are the recommended TypeScript tsconfig configurations for running Node.js 10?

Can someone provide information on the necessary target/libs for enabling Node.js v10.x to utilize async/await without generators? I have found plenty of resources for node 8 but not as much for node 10. ...

The installation of webtorrent-hybrid failed due to the error message "node-pre-gyp: command not found"

I'm currently encountering an issue while attempting to install webtorrent-hybrid for developing an electron p2p application. Vue UI is the framework I am using to handle front-end development, and I have successfully created a new project utilizing v ...

Why does TypeScript include a question mark next to the argument when GraphQL specifies it as nullable true?

// image.entity.ts import { Field, ObjectType } from '@nestjs/graphql'; import { Column, DeleteDateColumn, Entity, PrimaryGeneratedColumn, } from 'typeorm'; @ObjectType() @Entity() export class ImageEntity { @PrimaryGenerate ...

Bringing in a module that enhances a class

While scouring for a method to rotate markers using leaflet.js, I stumbled upon the module leaflet-rotatedmarker. After installing it via npm, I find myself at a loss on how to actually implement it. According to the readme, it simply extends the existing ...

React components need to refresh after fetching data from an API

I am currently working on a React application using TypeScript and integrating JSONPlaceholder for simulating API calls. I have successfully set up everything I need, but I am encountering an issue with re-rendering components that display response data fr ...

Visualizing Dynamic Path on VueJS Using Polygon Map

I am facing some issues with implementing Google Maps in Vue.js. I have created a polygon component as shown below: <script> export default { name: "MapPolygon", props: { google: { type: Object, ...

Utilizing Props in Vue.js to Access Data for v-model

After browsing online, I attempted to pass props to data in the following manner: Child Component: props: { idInput: { type: String, required: false }, nameInput: { type: String, required: false }, }, data() { return { id: this.idInput, na ...

Collaborating with Ladda button functionality

I have a button with ladda functionality, shown below. <button class="btn btn-primary btn-xs ladda-button" data-style="slide-left" data-size="xs" v-on:click="refreshPage()">Refresh</button> The onClick event is triggered by VueJs. When the b ...