Inquiring about Vue 3 with TypeScript and Enhancing Types for Compatibility with Plugins

I've been struggling to find a working example of how to implement type augmentation with Vue3 and TypeScript. I have searched for hours without success, trying to adapt the Vue2 documentation for Vue3.

It appears that the Vue object in the vue-class-component module needs to be augmented, but I'm unsure how to do it.

This is similar to my current implementation:

Any advice or guidance would be greatly appreciated.

https://v2.vuejs.org/v2/guide/typescript.html#Augmenting-Types-for-Use-with-Plugins

import { App, Plugin } from "vue";

export interface IHelloModule {
  sayHello: (name: string) => string;
}

export const helloPlugin: Plugin = (app: App, options) => {

  const helloModule:IHelloModule = {

    sayHello: function(name: string) {
      return `Hello ${name}`;
    }

  };

  app.provide("$hello", helloModule);
};
import { Vue } from 'vue-class-component';
import { IHelloModule } from "@/hello";

declare module "vue/types/vue" {
  interface Vue {
    $hello: IHelloModule;
  }
}

declare module "vue/types/vue" {
  interface VueConstructor {
    $auth: IHelloModule;
  }
}
<template>
  <div class="home">
     .....
  </div>
</template>

<script lang="ts">
import { Options, Vue } from 'vue-class-component';

@Options({
  components: {
  },
})
export default class Home extends Vue {
  mounted() {
    console.log(this.$hello.sayHello("World"))
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^
                     Neither TS nor vue-cli recognize this
  }
}
</script>
import { createApp } from "vue";
import App from "./App.vue";
import { helloPlugin } from "./hello";
import router from "./router";

createApp(App)
  .use(router, helloPlugin)
  .mount("#app");

Answer №1

Based on my understanding, it seems that vue-class-component is not fully compatible with Vue 3 yet. There are ongoing discussions regarding modifications needed in the library. Therefore, it is uncertain if the examples provided below will function properly with it. Nonetheless, I have made some adjustments to enhance plugin types.

hello.plugin.ts

import { App } from "vue";

export interface IHelloModule {
  sayHello: (name: string) => string;
}

export default {
  install: (app: App) => {
    const helloModule: IHelloModule = {
      sayHello: function(name: string) {
        return `Hello ${name}`;
      }
    }; 

    app.config.globalProperties.$hello = helloModule;
  }
}

declare module "@vue/runtime-core" {
  //Binding to `this` keyword
  interface ComponentCustomProperties {
    $hello: IHelloModule;
  }
}

I have defined the type within the plugin file itself, but you also have the option to define them in the shims-vue.d.ts file.

main.ts

import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import Hello from "./hello.plugin";

createApp(App)
  .use(router)
  .use(Hello)
  .mount("#app");

Hello.vue

<script lang="ts">
import { defineComponent } from "vue";

const Hello = defineComponent({
  mounted() {
    console.log(this.$hello.sayHello("World"));
  }
});

export default Hello;
</script>

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

Tips on how to effectively unit test error scenarios when creating a DOM element using Angular

I designed a feature to insert a canonical tag. Here is the code for the feature: createLinkForCanonicalURL(tagData) { try { if (!tagData) { return; } const link: HTMLLinkElement = this.dom.createElement('link'); ...

An instance of an abstract class in DI, using Angular version 5

I have multiple components that require three services to be injected simultaneously with the same instance. After that, I need to create a new instance of my class for injecting the services repeatedly. My initial idea was to design an abstract class and ...

The Mat-slide-toggle resembles a typical toggle switch, blending the functionalities of

I am facing an issue with a `mat-slide-toggle` on my angular page. Even though I have imported the necessary values in the module, the toggle is displayed as a normal checkbox once the page loads. HTML: <div style="width:100%;overflow:hidden"> < ...

Commit to calculating the total sum of each element using AngularJS

Trying to implement a like counter using Facebook's GRAPH API. I have a list of object IDs and for each ID, I make an API call to retrieve the number of likes and calculate a total. The issue arises as the API call returns a promise, causing only one ...

A guide to importing a Vue component in a JavaScript file

I am looking to achieve a specific behavior in my project: depending on a condition stored in my database, I want to load a particular vue.component instead of another. For example, within a file named discover.js, there is the following code: Vue.compone ...

Tips for adding an item to an array within a Map using functional programming in TypeScript/JavaScript

As I embark on my transition from object-oriented programming to functional programming in TypeScript, I am encountering challenges. I am trying to convert imperative TypeScript code into a more functional style, but I'm struggling with the following ...

"Utilizing variadic tuple types to implement the pipe function in TypeScript 4: A step-by-step guide

An illustration from the release notes of TypeScript 4 demonstrates the use of variadic tuple types to eliminate multiple overload definitions. It seems feasible to type the pipe function for any number of arguments. type F<P, R> = (p: P) => R ty ...

Inability to assign a value to an @input within an Angular project

I recently started using Angular and I'm currently trying to declare an input. Specifically, I need the input to be a number rather than a string in an object within an array. However, I'm encountering difficulties and I can't figure out wha ...

"Enhanced Laravel application incorporating Vue.js for data manipulation, utilizing Axios for API interactions

Lately, I've been diving into the world of Laravel and Vue.js. However, I've run into a roadblock while working with server-side interactions. After making a post request to the server and getting back a response, I noticed that there is an extra ...

Having difficulty categorizing an array with a multi-dimensional structure using a computed function in VueJS

I am currently using Vue to update an array called "draggables" based on the logic that if an object exists in another array of arrays named "dropzones," it should be removed from draggables. Each draggable item will only be present in the index of the mu ...

When implementing useFetch with onMounted in Nuxt3, data is not being fetched upon directly opening the link

In my project, I have implemented the useFetch function in the composition api to fetch data. The function is then called within the onMounted hook of components. Here is how it's done: Custom Composable: useShows.ts export function useShows(){ ...

Learn how to emphasize the category of an object property in vue.js using laravel

Can someone help me with highlighting/toggling a class and displaying data using blade/server-side in passing props? Here is the code snippet in blade: <chat-app :respondent="{{ $user[0]->respondent }}" :user="{{ auth()->user() }}"></chat-a ...

What causes RangeError: Maximum call stack size exceeded when Element UI event handlers are triggered?

I'm currently working on setting up a form and validating it with Element UI. Despite closely following the documentation, I am encountering an issue where clicking or typing into the input boxes triggers a RangeError: Maximum call stack size exceeded ...

Tips for properly narrowing a function parameter that includes "an object key or a function"

Working on a function to retrieve a property using either a string key or a callback, I've encountered an issue with TypeScript narrowing the type parameter. Here is the function in question: function get<T, V>(value: T, fn: (value: T) => V) ...

Troublesome update: Migrating XState's Reddit example from Vue 2 to Vue 3

Recently, I delved into the XState documentation and decided to explore the Reddit sample provided in the official guide. You can find it here: As I attempted to upgrade the sample implementation to Vue 3 following the work of Chris Hannaby, I encountered ...

`How can I retrieve data using PHP OOP and Vue.js together?`

I'm currently working on a project and facing a small issue. How can I retrieve records using PHP OOP with vue.js? Passing a variable in the URL within a class function seems to be challenging. I am utilizing Axios.js for sending AJAX requests. What a ...

Verify the status of the nested reactive forms to determine if the child form is in a dirty state

I am working on a form that consists of multiple sections within nested form groups. I need to find a way to detect when changes are made in a specific section. Here is the HTML structure: <div [formGroup]="formGroup"> <div formGroupN ...

Is it feasible to design a distinctive layout while utilizing a v-for loop in Vue 2?

I am currently in the process of designing a questionnaire. Within my array, each question is represented as an object. As I iterate through them using <component :is>, this component property guides how the question will be displayed - for example, ...

What is the method for obtaining the number of weeks since the epoch? Is it possible to

Currently, I am setting up a DynamoDb store for weekly reporting. My idea is to use the week number since 1970 as a unique identifier for each report record, similar to epoch milliseconds. Here are some questions I have: How can I determine the current w ...

How can serverless platforms handle binary data such as PDF files?

I am currently experiencing an issue that involves uploading a PDF file in Vue.js to a serverless Node.js application, resulting in broken file content. This problem occurs due to the serverless platform incorrectly parsing binary data types. How can I e ...