3

I am new to Vue and Nuxt. Doing a tutorial with TypeScript currently. It throws me a bunch of errors of Property 'x' does not exist on type 'y'. An example below;

ERROR in components/AboutMe.vue:56:27
TS2339: Property 'routes' does not exist on type '{ components: { CButton: any; }; props: { user: { type: ObjectConstructor; default: undefined; }; }; data(): { expand: boolean; showTitle: boolean; showReadMore: boolean; routes: string[]; compiledBio: string; }; beforeMount(): void; mounted(): void; }'.
    54 |   },
    55 |   mounted() {
  > 56 |     this.showTitle = this.routes.every((r) => this.$route.name !== r)
       |                           ^^^^^^
    57 |     if (this.$route.name === `users-userSlug`) {
    58 |       this.expand = true
    59 |       this.showReadMore = false

Others are Property 'showTitle' does not exist, 'expand' and etc. Basically everything with this. throws errors.

This is the <script block of AboutMe.vue component.

<script lang="ts">
import { CButton } from '@chakra-ui/vue'

export default {
  components: {
    CButton,
  },
  props: {
    user: {
      type: Object,
      default: undefined,
    },
  },
  data() {
    return {
      expand: false,
      showTitle: false,
      showReadMore: true,
      routes: [`users-userSlug-posts`, `users-userSlug`],
      compiledBio: ``,
    }
  },
  mounted() {
    this.showTitle = this.routes.every((r) => this.$route.name !== r)
    if (this.$route.name === `users-userSlug`) {
      this.expand = true
      this.showReadMore = false
    }
  },
}
</script>

What I am doing wrong?

I am using nuxt.js (v2.14.6)

Edit 1 for @BoussadjraBrahim

I added Vue.extend({}) and now most errors go away. But some of them still exist.

ERROR in components/Description.vue:138:10
TS2339: Property 'showAboutUs' does not exist on type 'CombinedVueInstance<Vue, unknown, unknown, unknown, Readonly<{ post: any; }>>'.
    136 |   },
    137 |   mounted() {
  > 138 |     this.showAboutUs = this.$route.name !== `users-userSlug-posts`
        |          ^^^^^^^^^^^
    139 |   },
    140 |   methods: {
    141 |     open() {

ERROR in components/Description.vue:142:12
TS2339: Property 'isOpen' does not exist on type 'CombinedVueInstance<Vue, unknown, unknown, unknown, Readonly<{ post: any; }>>'.
    140 |   methods: {
    141 |     open() {
  > 142 |       this.isOpen = true
        |            ^^^^^^
    143 |     },
    144 |     close() {
    145 |       this.isOpen = false
export default Vue.extend({
  data() {
    const showAboutUs: Boolean = false
    const isOpen: Boolean = false

    return {
      showAboutUs,
      isOpen,
    }
  },
  mounted() {
    this.showAboutUs = this.$route.name !== `users-userSlug-posts`
  },
  methods: {
    open() {
      this.isOpen = true
    },
    close() {
      this.isOpen = false
    },
  },
})
3
  • That means that this doesn't have "routes". You're embedding routes into the return of the data method. You're going to have to add them as a property on the AboutMe.vue component if you want to access them as this.routes. Alternately, you could do this.data().routes Commented Dec 9, 2020 at 17:16
  • How do I add them as property? Commented Dec 9, 2020 at 17:22
  • It looks like you are using things on the Vue component type. You need to tell typescript that this object is a vue component. I don't know Vue, so I can't really help you with that. Commented Dec 9, 2020 at 17:24

2 Answers 2

9

To get types inference you should create the component using Vue.extend({}) :

<script lang="ts">
import { CButton } from '@chakra-ui/vue'

import  Vue from "vue"

export default Vue.extend({
  components: {
    CButton,
  },
  props: {
    user: {
      type: Object,
      default: undefined,
    },
  },
  data() {
    return {
      expand: false,
      showTitle: false,
      showReadMore: true,
      routes: [`users-userSlug-posts`, `users-userSlug`],
      compiledBio: ``,
    }
  },
  mounted() {
    this.showTitle = this.routes.every((r) => this.$route.name !== r)
    if (this.$route.name === `users-userSlug`) {
      this.expand = true
      this.showReadMore = false
    }
  },
})
</script>

I recommend to type your data properties to enforce the component typing :

 data() {
    const routes:Array<string>: [`users-userSlug-posts`, `users-userSlug`];
  // do the same thing with the other properties
    return {
      expand: false,
      showTitle: false,
      showReadMore: true,
      routes,
      compiledBio: ``,
    }
  },

Edit long-sun-7944y

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks a lot! I have been search for this for hours. But how did you know that? Where is it specificated at documentation?
@boussadjra-brahim One question: should this be done on all components? I thought the settings in the vue-shim.d.ts file would do this.
@JG_GJ this should be done for all components
3

Try to use Vue.extend({})

Example:

<script lang="ts">
import { CButton } from '@chakra-ui/vue'
import  Vue from "vue"

export default Vue.extend({
  components: {
    CButton,
  },
  props: {
    user: {
      type: Object,
      default: undefined,
    },
  },
...
</script>

Hopefully this helps you

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.