Nuxt.js с помощью TypeScript: свойство ‘x’ не существует для типа ‘y’

#javascript #typescript #vue.js #nuxt.js

#javascript #typescript #vue.js #nuxt.js

Вопрос:

Я новичок в Vue и Nuxt. В настоящее время выполняю учебник по TypeScript. Это выдает мне кучу ошибок Property 'x' does not exist on type 'y'. в примере ниже;

 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
 

Другие есть Property 'showTitle' does not exist , 'expand' и т.д. В основном все с this. ошибками.

Это <script блок AboutMe.vue компонента.

 <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>
 

Пожалуйста, помогите мне, что я делаю не так?


nuxt.js (версия 2.14.6)


Редактирование 1: ответ на @BoussadjraBrahim

Спасибо, я добавил Vue.extend({}) , и теперь большинство ошибок исчезают. Но некоторые из них все еще существуют.

 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
    },
  },
})
 

Комментарии:

1. Это означает, что у этого нет «маршрутов». Вы встраиваете маршруты в возвращаемый метод данных. Вам нужно будет добавить их в качестве свойства в компоненте AboutMe.vue, если вы хотите получить к ним доступ как this.routes. В качестве альтернативы вы могли бы сделать это.data().routes

2. Как мне добавить их в качестве свойства?

3. Похоже, вы используете вещи для типа компонента Vue. Вам нужно сообщить typescript, что этот объект является компонентом vue. Я не знаю Vue, поэтому я не могу вам в этом помочь.

Ответ №1:

Чтобы получить вывод типов, вы должны создать компонент с помощью 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>
 

Я рекомендую ввести ваши свойства данных для принудительного ввода компонента :

  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: ``,
    }
  },
 

Редактировать long-sun-7944y

Комментарии:

1. Большое спасибо! Я искал это часами. Но как вы это узнали? Где это указано в документации?

2. Я нашел его vuejs.org/v2/guide/typescript.html#Basic-Usage и здесь typescript.nuxtjs.org

3. @boussadjra-brahim Один вопрос: должно ли это быть сделано для всех компонентов? Я думал, что настройки в файле vue-shim.d.ts сделают это.

4. @JG_GJ это должно быть сделано для всех компонентов

Ответ №2:

Попробуйте использовать 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,
    },
  },
...
</script>
 

Надеюсь, это поможет вам