vue: Property 'xxx' does not exist on type CombinedVueInstance ?

Version

2.5.17

Reproduction link

Steps to reproduce

  1. use vue-cli init a ts hello-world project .
  2. code like that
<script lang="ts">
import Vue from "vue";
export default Vue.extend({
  name: "HelloWorld",
  props: {
    msg: String
  },
  data():any {
    return {
      wtf: this.initData(), // throw ts error : Property 'initData' does not exist on type 'CombinedVueInstance<Vue, {}, {}, {}, Readonly<{ msg: string; }>>'.
    }
  },
 
  methods: {
    initData():any {
        return {
          a: ''
        }
    },
  },
 
});
</script>

What is expected?

How can i fix it ?

What is actually happening?

Property ‘initData’ does not exist on type ‘CombinedVueInstance<Vue, {}, {}, {}, Readonly<{ msg: string; }>>’.

About this issue

  • Original URL
  • State: open
  • Created 6 years ago
  • Reactions: 88
  • Comments: 56 (6 by maintainers)

Commits related to this issue

Most upvoted comments

EDIT: See @IAMtheIAM’s answer below

I had this error while working inside of a computed property. My data and computed were organized like this:

export default Vue.extend({
    name: 'componentName',
    data() {
        return {
            myDataPoint: false,
        };
    },
    computed: {
        trueOrFalse() {
            return this.myDataPoint ? 'is-true' : 'is-false';
        }
    },
})

It would give me the same error (Property myDataPoint does not exist on type CombinedVueInstance…)

However, when I declared what type would be returned by the function, the error went away: (look to the trueOrFalse computed property for the change)

export default Vue.extend({
    name: 'componentName',
    data() {
        return {
            myDataPoint: false,
        };
    },
    computed: {
        // declare the type returned by your function/computed/method
        trueOrFalse(): string {
            return this.myDataPoint ? 'is-true' : 'is-false';
        }
    },
})

Hope this helps!

Since this appears to be only a typing issue and not a runtime issue, there is an (ugly?) workaround available: cast this as type any:

return {
  wtf: (this as any).initData(),
};

Additionally omit the () to store a reference to the method that is executable outside of the current scope, e.g. if you pass it to a child via a prop.

Since this appears to be only a typing issue and not a runtime issue, there is an (ugly?) workaround available: cast this as type any:

return {
  wtf: (this as any).initData(),
};

Additionally omit the () to store a reference to the method that is executable outside of the current scope, e.g. if you pass it to a child via a prop.

So is this the proposed solution at the moment?

This happens for all my methods and data properties. What’s the solution?

UPDATE: Apparently, you have to annotate the return type for your computed methods, otherwise all your methods and data properties won’t appear to typescript as if they are on the CombinedVueInstance. As soon as I did that, all errors went away regarding this.

+1 in 2021. 😅

TL:DR for anybody else coming from Google after hours of searching:

  • For those expecting a fix like me. Vue.js 2 development was stopped at end of 2020.
  • This issue is 3 years old. Yeah, it is.
  • If you don’t want use any hack. Yours options are: Vue 3 or class-components.

Hope it helps

Solution from @tipsy solved it for me. My use case was using mapState.

interface HomeMapState {
  plants: Plant[]
}

export default (Vue as VueConstructor<Vue & HomeMapState>).extend({
  name: 'Home',
  computed: {
    ...mapState<HomeState>('home', {
      plants: (state: HomeState) => state.plants,
    }),
    plantData(): Array<Plant | {}> {
      if (this.loading) {
        return new Array(5).fill({})
      }
      return this.plants
    },
  }
})

this.plants in plantData() was previously always yielding an error and couldn’t be found on the Vue instance.

Declare the return type worked for me as well… But such strange behavior.

I had the same error after adding head() section to nuxt vue page. After adding return type :any to head, the error disappeared. Maybe this will be helpful to somebody.

head(): any {

I also have this problem in vscode

I’m very new to TypeScript. I tried all the advice here without any success, but I managed to build on @danjohnso’s workaround to “solve” this with intersection types:

export default (Vue as VueConstructor<Vue & Interface1 & Interface2>).extend({

I have no idea if doing that is bad, but everything seems to work fine.

Edit: My issue is with properties from mixins not being recognized.

For those experiencing the same error thrown as a result of using mixins in Vue 2.x, I’m going to dump some information and the solutions I found in my research below.

Here’s a helpful explanation of why you’re having this problem:

This is because you’re importing Vue from ‘vue’ package, thus TypeScript doesn’t have a clue that somewhere else you added property $myGlobalProperty to it.

After researching and reading around online, the consensus everywhere (including this thread) seems to be that in order to get proper mixin typings without any complications or workarounds, you’ll want to upgrade to Vue 3.

If that isn’t an option for you right now, this answer is what helped us overcome it. We went with option 1 until we can discuss option 2, and it will do until we can find a less limiting solution.

Here are some other solutions I came across today:

+1 in 2021.

TL:DR for anybody else coming from Google after hours of searching:

  • For those expecting a fix like me. Vue.js 2 development was stopped at end of 2020.
  • This issue is 3 years old. Yeah, it is.
  • If you don’t want use any hack. Yours options are: Vue 3 or class-components.

Hope it helps

It’s still there in 3.0

InstanceType<typeof mixin> or use this mixins utility I made for Vuetify: https://github.com/vuetifyjs/vuetify/blob/master/packages/vuetify/src/util/mixins.ts

Vue 3 has proper typings for mixins.

I still struggling with this error. Declaring the return type on computed properties solve part of the errors. But it does not work for :

  • mixins imported and used in methods
  • module mixins
export default Vue.extend({
  name: 'ConfigrationOptions',
  mixins: [global],
  computed: {
    exportConfig(): string {
      return JSON.stringify(this.$store.state.scrape.list)
    }
  },
  methods: {
    importConfig() {
      const jsonImport = ((this.$refs.jsonImport as Vue).$el as HTMLInputElement).value
      if (this.isJson(jsonImport)) { // <-- this give me an error ('isJson' is a method from the custom imported mixin)
        this.$store.commit('scrape/import', jsonImport)
        this.makeToast('Import', 'success')
      } else {
        this.makeToast('Import', 'danger')
      }
    },
    makeToast(action: string, variant: string) {
      const textFromVariant = variant === 'success' ? 'sucess' : 'failed';
      this.$bvToast.toast(`${action} ${textFromVariant}`, { // <-- this give me an error ('$bvToast' is a bootstrap-vue mixin)
        title: `Configuration options`,
        variant: variant,
        solid: true,
      })
    },
  },
})

Anyone know how to fix this without using the ‘ugly’ workaround (this as any) ?

Having the same issue when using the new Vue.js Composition API with vscode-insiders. The code compiles without TS errors but vscode shows an error nonetheless.

image

// setup(props, context) { 
watch(
    () => context.root.$q.screen.width,
    () => setMiniState(undefined)
)

Details Version: typescript 3.8.3, eslint 6.8.0

Version: 1.46.0-insider (system setup)
Commit: d487078dc7fc1c276657cadb61b4f63833a8df55
Date: 2020-05-07T16:19:54.327Z
Electron: 7.2.4
Chrome: 78.0.3904.130
Node.js: 12.8.1
V8: 7.8.279.23-electron.0
OS: Windows_NT x64 10.0.14393

Possible related issues: #23987, #29511 #32573 #34999

Type declaration didn’t work here either as a workaorund. So this failed too in vscode:

watch(
   (): number => context.root.$q.screen.width,
   () => setMiniState(undefined)
)

I had this issue until I gave all my computed properties return types. However, Jest unit tests continued to throw the same TypeScript error.

I had to alter my expectation to follow this pattern:

expect((wrapper.vm as any).subtotalFormatted).toBe('£1,234.56');

Yuk! I hope this can be resolved soon.

I guess we should remove this type from data option function and make it as the same as other function this type. The use case that OP provides looks totally valid.

I also faced another use case which I need comprehensive this type in data function when writing some function in it.

data() {
  return {
    someFunc: () => {
      this.someComputed() // `this` type here should be comprehensive
    }
  }
}

As a similar case, this type of beforeCreate seems also to be removed.

But they probably breaks existing apps type checking as we need to explicitly declare data function return type since it no longer infers return type of data due to this restriction. I’m not sure how much the change affects the existing apps…

Adding a type to all computed properties fixed it here.

I am still experiencing the problems described in this ticket… 😕

My Setup:

  • Vue 3.0.11
  • Typescript 4.3.x
  • Single File Components defined by using defineComponent
<template>
  <div>Hello World 2</div>
</template>

<script lang="ts">
<template>
  <div>Hello World 2</div>
</template>

<script lang="ts">
import { defineComponent, PropType } from 'vue';

interface IHelloWorldObject {
  helloWorld: string;
}

interface IGoodbyeWorldObject {
  goodByWorld: string;
}

interface IData {
  goodByWorld: string;
  goodByWorldObject: IGoodbyeWorldObject;
}

export default defineComponent({
  name: 'HelloWorld',
  props: {
    helloWorld: {
      type: String,
      default: 'hello world',
      validator(value: string): boolean {
        return [
          'hello-world',
          'hello world',
          'hello.world',
        ].includes(value);
      },
    },
    helloWorldObject: {
      type: Object as PropType<IHelloWorldObject>,
      required: true,
    },
  },
  data(): IData {
    return {
      goodByWorld: 'Good By World',
      goodByWorldObject: {
        goodByWorld: 'Good By World Object',
      }
    };
  },
  computed: {
    halloWorldExtended(): string {
      // Property this.helloWorldObject does not exist on type ComponentPublicInstance
      return `${this.helloWorldObject.helloWorld}!`;
    },
  },
  mounted () {
    // Property this.helloWorldObject does not exist on type ComponentPublicInstance
    console.log(this.helloWorldObject.helloWorld)
    // Property this.helloWorldObject does not exist on type ComponentPublicInstance
    console.log(this.helloWorld)
    console.log(this.goodByWorld)
    console.log(this.goodByWorldObject.goodByWorld)
  }
});
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped></style>

I typed all return types of methods in computed / data. Typescript still says, that props being used in a method in computed / lifecycle / methods do not exist…

Update

It turned out, that the problem was the way, how my prop validator is written:

  • validator(value: string) { => props not defined when using in computed / lifecycle methods
  • validator: (value: string) => { => props all working when using in computed / lifecycle methods

After I figured it out, I have found other tickets describing this issue:

Thanks @IAMtheIAM, your hint solved it for me. I was having the issue with methods that called vuex actions - and I thought initially the error might be in the type resolution for the vuex actions somehow. But it turned out I had added another computed property in the component that did not have a return type set. Adding this one solved it for my case.

We can’t turn on strict mode yet. However, we migrated to Vue 3 in the meantime. From our side this issue is not relevant anymore.

I really can’t believe this nightmare for not using decorators, Even using a lot of typescript (Vues as VueConstructor...), It doesn’t infers the types at all, and you can’t access computed properties between them. This is such a downer. Thank you for you help everyone

This does not work with props:

After explicitly typing out the return type of the getHeight() function the errors went away. I’m glad i found this fix. Thanks to everyone 😃 code

Typescript 3.9 has made this even worse, I have to specify return types for methods too now.

👍

vue-tsx-support

Same here. Vue 2.5 has better type declaration support for TypeScript but this seems broken.