manidos
manidos

Reputation: 3464

How to export types from Vue3 component to global scope?

I have two globally registered components ParentComponent and ChildComponent. One of the advantages of global registration is that globally registered components are available everywhere in the app. In other words, I don't have to import them in other components to use them. Unfortunately, the same can not be said about types. To access a type from a component I need to import it (checkout ParentComponent code below) whether the component was globally registered or not. Is there a way to export a type from component to "global" scope and have it available anywhere in the app?

main.ts

import { createApp} from 'vue'

import App from './App.vue'
import ParentComponent from './ParentComponent.vue'
import ChildComponent from './ChildComponent.vue'

const app = createApp(App)

app.component('parent-component', ParentComponent)
app.component('child-component', ChildComponent)

app.mount('#app')

ChildComponent (excerpt)

export type ChildComponentEvent = {
  message: string
}

export default defineComponent({
  methods: {
    emitEvent () {
      const event: ChildComponentEvent = {
        message: 'Hello from child'
      }
      this.$emit('child-event', event)
    }
  }
})

ParentComponent (excerpt)

import { ChildComponentEvent } from './ChildComponent'

export default defineComponent({
  methods: {
    childEventHandler (event: ChildComponentEvent) {
      console.log(event)
    }
  }
})

Upvotes: 3

Views: 3145

Answers (1)

danielv
danielv

Reputation: 3097

First, just to set things clear. These are two different and unrelated concepts:

Vue's component registration lets you add components to your app instance to be used by various parts of your code at runtime without the need to explicitly load them each time. Vue apps don't have to use typescript.

Typescript's typing work at design and "compile" time, this information is omitted when typescript is compiled to javascript and has no effect at runtime. Typescript declarations and type imports/exports rules apply regardless if you write Vue or other app.

You can declare global types and interfaces in typescript. If you want to do this from a module (like the file units you use to declare your Vue components), you can use the declare global syntax:

declare global {
  interface SomeGlobalInterface {
    ...
  }
}

Within your Typescript project (as configured in the tsconfig.json file), those types will be globally available.

It is generally advised to avoid global type declarations, it can lead to conflicts and missing types (like when you try to import modules that use global types in a different tsconfig environment, which is often the case in unit testing, for example).

It usually better for each logical unit of code to declare and export its types to be imported from anywhere they are needed, even if it makes the code more verbose. You can group related types in a single module and only import its types.

Use typescript's import type syntax (see modules docs) when you only need the typing and not the values. This can help avoid loading unnecessary modules at runtime and prevent module circular references.

Upvotes: 2

Related Questions