Subscribe on changes!

TS2339: Property 'xxx' does not exist on type '

avatar
Dec 6th 2022

Vue version

3.2.25

Steps to reproduce

  • father component
setup() {
// 弹窗dom对象
    const timingManageDrawerRef = ref<InstanceType<typeof TimingManageDrawer>>()

    const openModal = (name: 'timing' | 'record' | 'version' | 'treeView') => {
      timingManageDrawerRef?.value?.openDrawer() // this ts error
    }
}
return () => () {
 <TimingManageDrawer ref={timingManageDrawerRef}></TimingManageDrawer>
}
  • child
setup() {
    const openDrawer = () => {
      variables.visible = true
    }

    ctx.expose({ openDrawer })
}

What is actually happening?

image

Any additional comments?

No response

avatar
Dec 6th 2022

Well I think there are two solutions to this problem. If you don't use script-setup I think you simply have to export Api interface from Child component and use it as ref's type, otherwise it just doesn't work

Parent.vue

<script lang="ts">
  import { ref } from "vue";
  import Child, { type Api } from "./Child.vue";

  export default {
    setup() {
      const child = ref<Api>();

      child.value?.openDrawer();

      return { child }
    }
  }
</script>

<template>
  <Child ref="child" />
</template>

Child.vue

<script lang="ts">
  export interface Api {
    openDrawer(): void;
  }

  export default {
    setup(props, { expose }) {
      function openDrawer() {}

      expose({ 
        openDrawer, 
      } as Api);
    },
  };
</script>

<template></template>

You can help youself and start using mentioned script-setup with volar extension (guide) which will make work with TS easier for you.

Parent.vue

<script setup lang="ts">
  import { ref } from "vue";
  import Child from "./Child.vue";

  const child = ref<InstanceType<typeof Child>>();

  child.value?.openDrawer()
</script>

<template>
  <Child ref="child" />
</template>

Child.vue

<script setup lang="ts">
  function openDrawer() {}

  defineExpose({ openDrawer });
</script>

<template></template>

However, I see that your IDE is WebStorm. Guide mentions that WS provides out-of-the-box support for both TypeScript and vue. I personally don't use it, so I can't confirm if my examples works, but hope they do.

avatar
Dec 16th 2022

Well I think there are two solutions to this problem. If you don't use script-setup I think you simply have to export Api interface from Child component and use it as ref's type, otherwise it just doesn't work

Parent.vue

<script lang="ts">
  import { ref } from "vue";
  import Child, { type Api } from "./Child.vue";

  export default {
    setup() {
      const child = ref<Api>();

      child.value?.openDrawer();

      return { child }
    }
  }
</script>

<template>
  <Child ref="child" />
</template>

Child.vue

<script lang="ts">
  export interface Api {
    openDrawer(): void;
  }

  export default {
    setup(props, { expose }) {
      function openDrawer() {}

      expose({ 
        openDrawer, 
      } as Api);
    },
  };
</script>

<template></template>

You can help youself and start using mentioned script-setup with volar extension (guide) which will make work with TS easier for you.

Parent.vue

<script setup lang="ts">
  import { ref } from "vue";
  import Child from "./Child.vue";

  const child = ref<InstanceType<typeof Child>>();

  child.value?.openDrawer()
</script>

<template>
  <Child ref="child" />
</template>

Child.vue

<script setup lang="ts">
  function openDrawer() {}

  defineExpose({ openDrawer });
</script>

<template></template>

However, I see that your IDE is WebStorm. Guide mentions that WS provides out-of-the-box support for both TypeScript and vue. I personally don't use it, so I can't confirm if my examples works, but hope they do.

thank you very much, this first function slove me problem.