I have the below Vue component:
<template>
<v-snackbar bottom :color="color" v-model="snackbar">
{{ msg }}
<v-btn flat @click.native="close()">Close</v-btn>
</v-snackbar>
</template>
<script lang="ts">
import Vue from 'vue';
import VueEvent from '../../VueEvent';
export default Vue.extend({
data(): object {
return {
snackbar: false,
msg: '',
color: '',
};
},
created() {
VueEvent.listen('snackbar', (data) => {
this.snackbar = true;
this.msg = data.msg;
this.color = data.color;
});
this.malert();
},
methods: {
close(): void {
this.snackbar = false;
}
}
});
</script>
<style scoped>
</style>
When Typescript compiles I get the following error:
Property 'snackbar' does not exist on type 'CombinedVueInstance<Vue, object, { close(): void; }, {}, Readonly<Record<never, any>>>'.
28 | methods: {
29 | close(): void {
> 30 | this.snackbar = false;
| ^
31 | }
32 | }
33 | });
Does anyone know how I can solve this problem, or explain why its happening?
Well, I don't have a good answer for you, but I have theory:
The original type declaration resides in vue/types/options.d.ts:
type DefaultData<V> = object | ((this: V) => object); // here is the kicker
Data=DefaultData<V>
data?: Data;
And I found that:
data():object { ... // this.snackbar does not exist
data(){ ... // this.snackbar does exist.
data(): any { ... // this.snackbar does exist.
data(): { snackbar: boolean; msg: string; color: string } { ... // Also valid
I think without your object declaration typescript will think that data
is DefaultData<V> = object
. But once you say it returns an object, data will suddenly match ((this: V) => object)
instead. Now typescript expects this
to be of type V
(which I assume is a vue-instance) and since that vue instance does not have a snackbar in it's definition, boom, typescript throws.
Lot's of guessing here, but I think pretty much anything except explicitly returning object
would work to not match that second signature in DefaultData<V>
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With