Component is indeed the correct type, as you've attempted, but you need to import it before use:
<script setup lang="ts">
import type { Component } from 'vue'
⋮
interface Props {
header?: Component
body?: Component
footer?: Component
}
const fragments: Props = {
header: FragProfile,
body: FragSubject,
footer: TypeSection
}
</script>
demo
Answer from tony19 on Stack Overflow
» npm install vue-generate-component-typescript
vue.js - How to get a component type so I can use it in a typescript interface - Vue 3 - Stack Overflow
vue.js - Generate d.ts file for Vue components written in Typescript - Stack Overflow
Working with slots in Vue 3 + TypeScript.
Why does importing components gives an error?
Videos
Component is indeed the correct type, as you've attempted, but you need to import it before use:
<script setup lang="ts">
import type { Component } from 'vue'
⋮
interface Props {
header?: Component
body?: Component
footer?: Component
}
const fragments: Props = {
header: FragProfile,
body: FragSubject,
footer: TypeSection
}
</script>
demo
Here is a detailed example of dynamic type-safe component loading as it is tricky to get right.
You can use generic Component<PropType> type to define components with similar parameters.
So for instance, to dynamically load all components of certain type you can use this loader function.
type FilterCompName = "EasyFilter" | "NameFilter"
type Proptype = { filter: string }
type FilteredComponent = Component<Proptype>
function loader<FilteredComponent>(comp: FilterCompName ): FilteredComponent {
return defineAsyncComponent(() => import(`./comps/${comp}.vue`))
}
Then you will have mapping array
type FilterNames= "easyFilter" | "nameFilter"
const comps: { [id in FilterNames]: FilteredComponent} = {
"easyFilter": loader("EasyFilter"),
"nameFilter": loader("NameFilter")
} as const
Then just define ref for name and computed for the dynamically loaded async component
const filterString= ref<string>("test")
const name = ref<FilterNames>("easyFilter")
const ViewComp: ComputedRef<FilteredComponent> = computed(() => comps[name .value])
Then in template section you get dynamic component with correctly typed propertis
<template>
<component :is="ViewComp" :filter="filterString" />
</template>
Here is a working example
You can use the official vue-tsc package.
execute:
npx vue-tsc --declaration --emitDeclarationOnly
see more info here: https://github.com/vuejs/language-tools/tree/master/packages/tsc#readme
Use rollup - I tried everything but it did not work with WebPack/vue-cli-service.
Here is my starter-template with rollup: https://github.com/MikeMitterer/vue-ts-sfc-starter
Hope this helps