schnetzi
schnetzi

Reputation: 169

How to use provide/inject with TypeScript but without vue-class-component

When I use provide/inject with class components everything works as expected. But when I use it in a "normal" vue component I get type-errors.

In this example I get errors when referencing this.testService. The code works though.

export default Vue.extend({
  name: "HelloWorldBasic" as string,
  inject: ["testService"],

  computed: {
    message(): string | null {
      return this.testService ? this.testService.hello() : null;
    }
  }
});

Where did I make my mistake? How should I write the code?

I set up a small project to be able to reproduce it and work with it:

$ git clone [email protected]:schnetzi/vue-provide-inject.git
$ npm ci
$ npm start

Upvotes: 7

Views: 2440

Answers (2)

Eino Gourdin
Eino Gourdin

Reputation: 4507

An alternative to the inject attribute is to use the inject() method

  import { inject } from 'vue';

  // (...)

  data() {
    return {
      testService: inject('testService') as TestService,
    };
  },

After which you can use this.testService as you did: this.testService?.hello()

inject() can even take a default value as second parameter in case the injection isn't resolved.

Upvotes: 0

Varo
Varo

Reputation: 358

This is a bit tricky to do, but it is possible using the same workaround that is commonly used for mixins, which entails defining an interface for whatever you want to add to the Vue instance.

In your case, here's how it would be done:

import Vue_ from 'vue';
import MyTestServiceType from 'wherever/it/is';

interface HelloWorldBasicInjected {
  testService: MyTestServiceType
}

const Vue = Vue_ as VueConstructor<Vue_ & HelloWorldBasicInjected>
export default Vue.extend({
  name: "HelloWorldBasic" as string,
  inject: ["testService"],

  computed: {
    message(): string | null {
      return this.testService ? this.testService.hello() : null;
    }
  }
});

Upvotes: 6

Related Questions