Vue: In the TypeScript component, the error Property does not exist on type 'Vue'

Created on 25 Jun 2018  路  7Comments  路  Source: vuejs/vue

Version

2.5.16

Reproduction link

https://codesandbox.io/s/github/weihongyu12/vue-typescript-demo

Steps to reproduce

Uses @vue/cli to build the project. The configuration uses TypeScript. However, in the process of using, in the methods, there is no access to the computed. The construction does not exist on type 'Vue'.

<template>
  <ul
    v-if="show"
    class="picker">
    <li
      v-for="(item, index) of pickerList"
      :key="index">{{ item }}</li>
  </ul>
</template>

<script lang="ts">
import Vue from 'vue';

export default Vue.extend({
  name : 'Picker',
  props: {
    columns: {
      type: Array,
      default: [],
    },
    show: {
      type: Boolean ,
      default: false,
    },
  },
  computed: {
    pickerList(): Array<string> {
      const arr = [];
      const columns: any = this.columns;
      for (const item of columns) {
        arr.push(item.title);
      }
      return arr;
    },
    pickerMap() : Map<string, number> {
      const map = new Map();
      const columns: any = this.columns;
      for (const item of columns) {
        map.set(item.title, item.id);
      }
      return map;
    },
  },
  methods: {
    onConfirm(value: string): void {
      const resumeId = this.pickerMap.get(value);  // Property 'pickerMap' does not exist on type 'Vue'.
      this.$emit('confirm', resumeId);
    },
  },
});
</script>

What is expected?

I don't know if it's because of my writing, or because of the configuration that caused me this error. I wrote the code based on the official document. I believe it can be build successfully.

What is actually happening?

When I run npm run build, an error Property 'pickerMap' does not exist on type 'Vue'. The complete prompt is as follows:

ERROR in E:/project/demo/src/components/picker.vue
44:29 Property 'pickerMap' does not exist on type 'Vue'.
聽聽聽聽 42 | methods: {
聽聽聽聽 43 | onConfirm(value: string): void {
聽聽 > 44 | const resumeId = this.pickerMap.get(value);
聽聽聽聽聽聽聽 | ^
聽聽聽聽 45 | this.$emit('confirm', resumeId);
聽聽聽聽 46 | },
聽聽聽聽 47 | },

I do not know of any reason for this error. It is imperative that I have a friend to help me solve this error, but I hope that the official can speed up the improvement of TypeScript's documentation, because I believe TypeScript will become popular. Thank you.

Most helpful comment

Official documentation is really too little for TypeScript

All 7 comments

Duplicate of https://github.com/vuejs/vue/issues/6841

馃槙
I think we need to address this issue in the docs if 2.6 isn't going to be released any time soon.

Official documentation is really too little for TypeScript

I got the same errors with vue 2.8.2 and Typescript 2.5.3. I fixed it by holding my Vue instance in a variable then giving it a type. This ensures TS will know about all Vue properties when you instatiate it using an options object.

var VueApp: any = Vue;

var App = new VueApp({
  el: "#app",
  data() {
     return {
        count: 0
     }
  },
  methods:{
    initialize() {
      this.count = count + 1; // Should work now
    }
  }
})

The trick is that it is TypeScript, you'll need to define an interface that your component implements. This is the blessing and curse of Statically Types languages. Take for instance this example with my Nav component in Vue:

<template lang="pug">
nav.navbar(role="navigation" aria-label="main navigation")
    <!-- Branding and Hamburger -->
    .navbar-brand
        a.navbar-item(href="https://bulma.io")
            img(src="https://bulma.io/images/bulma-logo.png" alt="Bulma: a modern CSS framework based on Flexbox" width="112" height="28")
        a.navbar-burger(role="button" aria-label="menu" aria-expanded="false")
            span(aria-hidden="true")
            span(aria-hidden="true")
            span(aria-hidden="true")
    <!-- Navbar Menu -->
    <!-- Hidden on mobile, needs .is-active added at those sizes -->
    div(v-bind:class="{navBarMenuClass}")

</template>

<script lang="ts">

import { Component, Prop, Vue } from 'vue-property-decorator';

const navbarMenuBaseClass = 'navbar-menu';

interface INav {
    menuIsActive: boolean;
}

@Component
export default class Nav extends Vue implements INav  {
    menuIsActive: boolean = false;

    computed() {
        return {
            navbarMenuClass: navbarMenuBaseClass + (this.menuIsActive ? 'is-active' : '')
        }
    }
}
</script>

Until I added the implemements INav and the INav interface definition, I was getting type errors for this.menuIsActive.

var VueApp: any = Vue;

That helped. Thanks.

But that is not a valid and scalable solution, if you have tons of components...

$router, $store, etc. are being injected into Vue Type in main.js with new Vue({...}). TypeScript cannot know that they are present in 'this'/Vue, because Vue Interface in vue.d.ts does not cover these keys. I think the Vue Interface in vue.d.ts should have optional parameters for those plugins(vuex, vue-router), so TS knows that they ($store, $router) could be present.

I opened the vue.d.ts and seen this
typescript extend<Data, Methods, Computed, PropNames extends string = never>(options?: ThisTypedComponentOptionsWithArrayProps<V, Data, Methods, Computed, PropNames>): ExtendedVue<V, Data, Methods, Computed, Record<PropNames, any>>;
this solved my issue
Vue.extend({

You can type Data, Methods, Computed and Props like this:

interface Props {
  columns: string[]
  show: boolean
}

interface Data {
  isVisible: boolean
}

interface Computed {
  pickerList: string[]
  pickerMap: Map<string, number>
}

interface Methods {
  onConfirm: (value: string) => void
}

export default Vue.extend<Data, Methods, Computed, Props>({
  methods: { ... },
  data() { ... },
  computed: { ... },
  props: { ... },
  render() { ... }
})

This way the Typescript errors should go away.
Note that for the example above to work, you need to have props defined as an object, not in the props: [] syntax. For the latter, the type definition needs to be different.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

paulpflug picture paulpflug  路  3Comments

loki0609 picture loki0609  路  3Comments

robertleeplummerjr picture robertleeplummerjr  路  3Comments

aviggngyv picture aviggngyv  路  3Comments

Jokcy picture Jokcy  路  3Comments