nuxt-community / nuxt-property-decorator

Property decorators for Nuxt (base on vue-property-decorator)
https://github.com/kaorun343/vue-property-decorator
MIT License
400 stars 34 forks source link

Injected plugin are not seen by tslint #32

Closed wSedlacek closed 5 years ago

wSedlacek commented 5 years ago

When using the inject function as documented in https://nuxtjs.org/guide/plugins/ under "Combined inject" the injected methods and objects are not seen by tslint when using nuxt-property-decorator.

Example:

plugins/my-plugin.ts

const myData = {
  someData : "data",
  someDataChange() {
    this.someData = "newData";
  }
}

export default (_: any, inject: any) => {
  inject("data", myData);
};

components/MyComponent.vue

<script lang="ts">
import { Vue, Component } from "nuxt-property-decorator";

@Component
export default class MyComponent extends Vue {
  public triggerDataChange() {
    this.$data.someDataChanage();
  }
}
</script>

In this example the someDataChanage() would be executed as expected by the browser but tslint would provide an error saying "Property '$data' does not exist on type 'MyComponent'."

When not using nuxt-property-decorator tslint is able to properly pick up on $data, it is only when using nuxt-property-decorator that such an error is shown.

A hacky workaround is to add public this.$data: any into the class definition of MyComponent and the error will no longer be shown and the code will be executed as expected however from my understanding this shouldn't be needed.

I am aware that removing lang="ts" removes this tslint error however then tslint provides a warning on all methods that public can only be used in a ts file, and if I remove public I get "The class property 'triggerDataChange' must be marked either 'private', 'public', or 'protected"

I could also just not understand how typscript works, but the strange part is the code executes even though tslint gives an error.

husayt commented 5 years ago

It is expected that typescript doesn't see injection, as you still need to add a type declaration. This is the way how I would solve this. Just add this to some d.ts file e.g. index.d.ts

declare module "vue/types/vue" {
  interface Vue {
    readonly $data: any
  }
}

and then in tsconfig.json

  "include": [
    "./index.d.ts",
....
  ],

Hope this helps