Home > Software design >  Vue3: How to type a component instance template ref with exposed methods?
Vue3: How to type a component instance template ref with exposed methods?

Time:04-13

I have this component A with an exposed method send

A.vue:

<script setup lang="ts">
function send(data: string) {
  console.log(data)
}

defineExpose({ send })
</script>

And the component B which imports this component

B.vue

<template>
  <ComponentA ref="a" />
</template>
<script setup lang="ts">
import ComponentA from '@/component-a.vue'

const a = ref()

onMounted(() => a.value.send(22)) // should be a type error
</script>

How do I type the imported component, so that when I call its methods through refs, it checks exposed method names and types of passed arguments?

I tried what I could google: ComponentPublicInstance<typeof ComponentA> but it doesn't seem to check the methods.

EDIT:

here's shims-vue.d.ts (as generated by vue-cli):

declare module '*.vue' {
  import type { DefineComponent } from 'vue'
  const component: DefineComponent<{}, {}, any>
  export default component
}

CodePudding user response:

As far as TypeScript is concerned, ComponentA is of type DefineComponent<{}, {}, any>, because your shims-vue.d.ts declares it as such. (I imagine you'll have more luck with import ComponentA as opposed to import { ComponentA }, too.) TypeScript does not understand how to parse Vue SFC files, so TypeScript is forced to trust your .d.ts file.

In screenshot of TypeScript error in action

  • Related