kaorun343 / vue-property-decorator

Vue.js and Property Decorator
MIT License
5.52k stars 380 forks source link

Vue router issue when using reflect metadata #197

Open moltar opened 5 years ago

moltar commented 5 years ago

When I enable reflect metadata as per doc, I get these errors:

"export 'RawLocation' was not found in 'vue-router'

This actually happens when setting emitDecoratorMetadata.

My use case is pretty simple:

import { RawLocation } from 'vue-router'

I just want to type annotate some code that it requires RawLocation-compatible data.

kaorun343 commented 5 years ago

@moltar

Hi.

Actually, this issue is caused by enabling emitDecoratorMetadata . I recommend you to set the option to false.

moltar commented 5 years ago

Hm, but the README says that it needs to be enabled.

https://github.com/kaorun343/vue-property-decorator#if-youd-like-to-set-type-property-of-each-prop-value-from-its-type-definition-you-can-use-reflect-metadata

Thanks!

moltar commented 5 years ago

Hi, why was this closed? Is this not a valid issue?

kaorun343 commented 5 years ago

It is optional to set emitDecoratorMetadata to true.

@Component
class MyComponent extends Vue {
  @Prop() age: number
}

When the component is wrote like this, the component is going to be converted to like this if the options is set to false.

Vue.extend({
  name: 'MyComponent',
  props: {
    age: { type: null }
  }
})

Whereas, if it is set to true and reflect-metadata is imported, the component is going to be converted to like this.

Vue.extend({
  name: 'MyComponent',
  props: {
    // `type` is automatically set based on its type definition in TypeScript world
    age: { type: Number } 
  }
})

Reference https://github.com/kaorun343/vue-property-decorator/issues/107

kaorun343 commented 5 years ago

As well as the issue I introduced, it's seemed that you are using @Watch property.

@Component
class MyComponent extends Vue {
  @Watch('rawLocation')
  onChange(newLocation: RawLocation) {}
}

When emitDecoratorMetadata is enabled, TypeScript compiler try to refer RawLocation object to pass the type information ( for example, newLocation is a RawLocation). The type definition of RawLocation is defined, but it is not exported as an actual JS value.

moltar commented 5 years ago

Whereas, if it is set to true and reflect-metadata is imported, the component is going to be converted to like this.

Right, and that is exactly what I wanted! :)

As well as the issue I introduced, it's seemed that you are using @Watch property.

I am not using Watch in the same context as RawLocation.


Thank you!

fluidsonic commented 4 years ago

Same issue here, with @Prop.

import { RawLocation } from 'vue-router'
// …
@Prop() to?: RawLocation    // warning: export 'RawLocation' was not found in 'vue-router'

I've worked around it by setting the type explicitly:

import { RawLocation } from 'vue-router'
// …
@Prop({ type: [Object, String] }) to?: RawLocation

It would be nice if vue-property-decorator would simply treat missing exports as Object. The following behavior was unexpected:

import { Location } from 'vue-router'
// …
@Prop() to?: string | Location    // warning: export 'Location' was not found in 'vue-router'

In this case the library infers type as Object but there's clearly a string in there, so it should be [Object, String].