Resolve "Property does not exist on type 'Vue'" error

58,614

Solution 1

you should make a declare for import *.vue file.

such as:

vue-file-import.d.ts

declare module "*.vue" {
   import Vue from "vue";
   export default Vue;
}

Solution 2

I had the same problem but with exporting component. Some vs code snippets create template without necessary typo like this below

export default {
  data() {
    return {
      x: "something",
    };
  },
  methods: {
    rename(name: string) {
      this.x = name;
    },
    
  },
};

The problem was i did not add defineComponent() to export default. So should be


import { defineComponent } from "vue";

export default defineComponent({
  data() {
    return {
      x: "something",
    };
  },
  methods: {
    rename(name: string) {
      this.x = name;
    },
    
  },
});

Make sure you exporting component with defineComponent() function

Solution 3

Adding another answer to bring together several things you may need to fix.

Ensure you include the ".vue" extension in the filename being imported

While both

import Competency from '../components/competency';

and

import Competency from '../components/competency.vue';

may compile successfully, the second one will help avoid the error appearing in some IDE's such as VS Code.

Add a shim typings file

As @May pointed out above, you need a file that imports and re-exports the type of "Vue". In @May's answer, it is named vue-file-import.d.ts, but elsewhere on the internet it is commonly called vue-shim.d.ts. Regardless of name, the content needed is the same:

// vue-file-import.d.ts

declare module "*.vue" {
   import Vue from "vue";
   export default Vue;
}

Try different locations for the shim file.

Originally I put it in /src. I found this had an odd effect. Sometimes it worked, i.e. the VS Code error messages disappeared; and other times it didn't, they reappeared. This happened dynamically as I moved around the project editing different files.

I later found the suggestion for a shim file of identical content, but to be placed in /typings. I tried this and it worked consistently. Other people seem quite happy with the /src location.

Solution 4

I was trying to follow this page https://vuejs.org/v2/guide/routing.html and was getting the same TypeScript errors, I fixed it by casting the Vue instance to type any like this

    new Vue({
        el: '#app',
        data: {
            currentRoute: window.location.pathname
        },
        computed: {
            ViewComponent() {
                return routes[(this as any).currentRoute] || routes['/']
            }
        },
        render (h) { return h((this as any).ViewComponent) }
    })

Solution 5

I suggest using class based components when using typescript (have a look at this "Writing Class-Based Components with Vue.js and TypeScript"). This is the only way to have type safe code and use autocomplete functionality of your IDE

You need to install vue-property-decorator

Here is an example of class based component:

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

@Component({
  props: {
    prop1: { type: Number }
  }
})
export default class MyComponent extends Vue {
  // This is how you define computed
  get myComputedRoute() {
     return this.$route.params;
  }

  @Watch('myComputedRoute')
  onPropertyChanged(value: string, oldValue: string) {
    // Do stuff with the watcher here.
  }
}
Share:
58,614
Tim Hutchison
Author by

Tim Hutchison

I'm a Senior Software Engineer at Cohen & Company in Cleveland, OH. We build internal applications using Typescript, Vuejs, Nodejs, and Expressjs that improve the efficiency and operations of the company. In my free time I enjoy playing various sports (primarily golf and ping pong), watching football and hockey, mentoring high schoolers, reading, and spending time with friends.

Updated on February 11, 2022

Comments

  • Tim Hutchison
    Tim Hutchison about 2 years

    I am using Typescript with Vuejs to build an application. I have several stand alone components (.vue) files that I am importing into a Typescript (.ts) file. In the Typescript file, I am importing Vue from the npm Vue library and then creating a new Vue to display my components. The error that I am seeing is:

    Property x does not exist on type 'Vue'

    My build system is Webpack with tsc. Why am I getting this error and how can I resolve it?

    main.ts

    import Vue from 'vue';
    import Competency from '../components/competency.vue';
    
    new Vue({
      el: "#app",
      components: {
        'competency': Competency
      },
      data:{
        count: 0
      },
      methods:{
        initialize: function(){
          this.count = count + 1; // Errors here with Property count does not exist on type vue
        }
      }
    })
    

    tsconfig

    {
      "compilerOptions": {
        // "allowJs": true,
        "allowSyntheticDefaultImports": true,
        "experimentalDecorators": true,
        "lib": [
          "es2015",
          "dom",
          "es2015.promise"
        ],
        "module": "es2015",
        "moduleResolution": "node",
        "noEmitOnError": true,
        "noImplicitAny": false,
        //"outDir": "./build/",
        "removeComments": false,
        "sourceMap": true,
        "target": "es5"
    
      },
      "exclude": [
        "./node_modules",
        "wwwroot",
        "./Model"
      ],
      "include": [
        "./CCSEQ",
        "./WebResources"
      ]
    }
    

    webpack.config.js

    const path = require('path');
    const webpack = require('webpack');
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    const CleanWebpackPlugin = require('clean-webpack-plugin');
    
    module.exports = {
        entry: {
            Evaluations: './WebResources/js/main.ts'
        },
        devServer: {
            contentBase: './dist'
        },
        module: {
            rules: [{
                    test: /\.ts$/,
                    exclude: /node_modules|vue\/src/,
                    loader: 'ts-loader',
                    exclude: /node_modules/,
                    options: {
                        appendTsSuffixTo: [/\.vue$/]
                    }
                },
                {
                    test: /\.vue$/,
                    loader: 'vue-loader',
                    options: {
                        esModule: true
                    }
                },
                {
                    test: /\.css$/,
                    use: [
                        'style-loader',
                        'css-loader'
                    ]
                },
                {
                    test: /\.(png|svg|jpg|gif)$/,
                    use: [
                        'file-loader'
                    ]
                },
            ]
        },
        resolve: {
            extensions: [".tsx", ".ts", ".js"],
            alias: {
                'vue$': 'vue/dist/vue.esm.js'
            }
        },
        plugins: [
            new CleanWebpackPlugin(['dist']),
            new HtmlWebpackPlugin({
                filename: 'Evaluations.html',
                template: './WebResources/html/Evaluations.html'
            }), new HtmlWebpackPlugin({
                filename: 'ExpenseUpload.html',
                template: './WebResources/html/ExpenseUpload.html'
            }), new webpack.optimize.CommonsChunkPlugin({
                name: 'WebAPI'
            })
        ],
        output: {
            filename: '[name].bundle.js',
            path: path.resolve(__dirname, 'dist')
        }
    }