Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue JS typescript component cannot find inject instance properties

I'm working with typescript and vue.

In my app there is a service which is a global for every sub component.

I found this native vue solution on vue JS to inject this property on the child components.

on main.ts

const service = new MyService(...);

new Vue({
  router,
  provide() { return { service }; } // provide the service to be injected
  render: h => h(App),
}).$mount("#app");

on any typescript vue component

import Vue from "vue";

export default Vue.extend({
  inject: ["service"], // inject the service
  mounted() {
    console.log(this.service); // this.service does exists 
  },
});

This way I'm able to get the injected service on my Child components.

However I'm getting the fallowing error

Property 'service' does not exist on type 'CombinedVueInstance < Vue, {}, {}, {}, Readonly < Record < never, any > > >'.

How can I solve this typescript compilation error?

like image 721
Daniel Santos Avatar asked Mar 15 '19 13:03

Daniel Santos


People also ask

Does vue2 support TypeScript?

You should also be familiar with Vue, vue-loader, and webpack. Vue 2 already has good support for TypeScript, and the recently published Vue 2.7 backported a lot of useful features from Vue 3, like composition API, <script setup> , and defineComponent , further improving the developer experience of TypeScript in Vue.

What is defineComponent in vue3?

defineComponent({ setup: function , name: 'some name' }); As you see, all these cases are responsible for different scenarios, yet the return type is always the same: a defineComponent interface with all the types you need to apply for the props, data and the other settings that are needed for the component.


1 Answers

Using plugins

If you whant to use some service in all Vue components, you can try to use plugins.
In main.ts you just import it:

import Vue from "vue";
import "@/plugins/myService";

In plugins/myService.ts you must write someting like this:

import _Vue from "vue";
import MyService from "@/services/MyService";

export default function MyServicePlugin(Vue: typeof _Vue, options?: any): void {
    Vue.prototype.$myService = new MyService(...); // you can import 'service' from other place
}

_Vue.use(MyServicePlugin);

And in any vue component you can use this:

<template>
  <div> {{ $myService.name }}</div>
</template>
<script lang="ts">
  import { Component, Vue } from "vue-property-decorator";

  @Component
  export default class MyComponent extends Vue {
    private created() {
      const some = this.$myService.getStuff();
    }
  }
</script>

Don't forget to declare $myService on d.ts file. Somewhere in your project add file myService.d.ts with the following content:

import MyService from "@/services/MyService";

declare module "vue/types/vue" {
  interface Vue {
      $myService: MyService;
  }
}
like image 158
Alex Avatar answered Sep 23 '22 09:09

Alex