vuejs / core

🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
https://vuejs.org/
MIT License
47.36k stars 8.28k forks source link

Property 'xxx' does not exist on type 'ComponentPublicInstance' #2775

Closed terminalqo closed 3 years ago

terminalqo commented 3 years ago

Version

"vue": "^3.0.0" "eslint": "^6.7.2" "typescript": "~3.9.3" vue-cli@latest

Reproduction link

[]()

Steps to reproduce

import { defineComponent, PropType } from "vue";

interface ComplexMessage {
  title: string;
  okMessage: string;
  cancelMessage: string;
}

const BarCharts = defineComponent({
  setup() {},
  props: {
    message: {
      type: Object as PropType<ComplexMessage>,
      required: true,
      validator(message: ComplexMessage) {
        return !!message.title;
      }
    }
  },
  data() {
    return {};
  },
  created() {
    console.log(this.message); // ts2339
  },
  render() {
    return <div>1</div>;
  }
});

export default BarCharts;

What is expected?

No ts warning

What is actually happening?

ts warning show:

Property 'message' does not exist on type 'ComponentPublicInstance<Readonly<{ [x: number]: string; } & { length?: number | undefined; toString?: string | undefined; toLocaleString?: string | undefined; concat?: string[] | undefined; join?: string | undefined; ... 17 more ...; flat?: unknown[] | undefined; }> | Readonly<...>, ... 8 more ..., ComponentOptionsB...'.
  Property 'message' does not exist on type '{ $: ComponentInternalInstance; $data: {}; $props: Readonly<{ [x: number]: string; } & { length?: number | undefined; toString?: string | undefined; toLocaleString?: string | undefined; ... 19 more ...; flat?: unknown[] | undefined; }> | Readonly<...>; ... 10 more ...; $watch(source: string | Function, cb: Function,...'.ts(2339)

file name: BarCharts.tsx, use vscode vetur@latest.

terminalqo commented 3 years ago

image

terminalqo commented 3 years ago

This is fine. image

but : https://v3.vuejs.org/guide/component-props.html#prop-validation image

Zcating commented 3 years ago

You should use arrow function while using validator or default attr. #2474

littlesmilelove commented 3 years ago

You should use arrow function while using validator or default attr. #2474

This answer is correct.

ravenclaw900 commented 3 years ago

I'm having the same problem, but with data instead of props. I don't have any validators or anything like that, and it works just fine when using javascript.

<script lang="ts">
export default {
  data() {
    return {
      platform: "x86_64"
    };
  },
  computed: {
    showMachines() {
      return this.platform === "arm" || this.platform === "aarch64"; // Error here, on platform
    },
    showAarch64() {
      return this.platform === "aarch64"; // Here too, same place
    }
  }
};
</script>
LinusBorg commented 3 years ago
  1. use defineComponent() to let TS know you are actually defining a Vue component
  2. try annotating the return values of the computed's:
showMachines(): boolean {

For more help, please use chat.vuejs.org

bobohuochai commented 3 years ago

I'm having the same problem, but with data instead of props. I don't have any validators or anything like that, and it works just fine when using javascript.

<script lang="ts">
export default {
  data() {
    return {
      platform: "x86_64"
    };
  },
  computed: {
    showMachines() {
      return this.platform === "arm" || this.platform === "aarch64"; // Error here, on platform
    },
    showAarch64() {
      return this.platform === "aarch64"; // Here too, same place
    }
  }
};
</script>

The same problem with you. It's confused.

LinusBorg commented 3 years ago

https://v3.vuejs.org/guide/typescript-support.html#annotating-return-types

nandodrw commented 3 years ago

@ravenclaw900 @bobohuochai as @LinusBorg point as soon you define the return types of your computed properties the types from the data properties will work just fine(looks like not doing it breaks all the typing on the component).

Liangzhihe commented 3 years ago
  1. use defineComponent() to let TS know you are actually defining a Vue component
  2. try annotating the return values of the computed's:
showMachines(): boolean {

For more help, please use chat.vuejs.org

thank you very much!

sakurawald commented 1 year ago
  1. use defineComponent() to let TS know you are actually defining a Vue component
  2. try annotating the return values of the computed's:
showMachines(): boolean {

For more help, please use chat.vuejs.org

This works. The problem of TypeScript

benjsmyth commented 1 year ago

I had this problem for objects that I was injecting into my component. For anyone having problems with typing injected data, the solution is to use the Composition API instead.

popring commented 1 year ago
  1. use defineComponent() to let TS know you are actually defining a Vue component
  2. try annotating the return values of the computed's:
showMachines(): boolean {

For more help, please use chat.vuejs.org

thanks, also correct resolve my problem, ts error with data.