How can I make a Vue component with a generic type parameter that extends the properties of the component? #15178
|
I'm working in creating a Vue component that can mount components from other frameworks. Don't worry about the mechanics of this action, as they are all complete and working. What I would love is for Intellisense to be able to show the properties of the mounted component as if they were properties of the container component itself. The main problem is type Props = TProps & {
/* own properties */
};
const props = defineProps<Props>();Is there a way to keep defineProps() happy while still extending the exposed properties type of the container component? |
Replies: 1 comment 2 replies
|
You've hit a real limit, not a syntax mistake. The way through is <script setup lang="ts" generic="TProps extends Record<string, any>">
const props = defineProps</* @vue-ignore */ TProps & {
component: unknown
}>()
</script>That tells the compiler to skip runtime prop generation for that type and keeps the type surface for TS, which is the part you actually want for Intellisense. The tradeoff: only your own props get a runtime declaration. I compiled the above with props: {
component: { type: null, required: true }
}No That's not a bug you can configure away, by the way. Vue has to emit the props list when it compiles your component, and |
You've hit a real limit, not a syntax mistake.
definePropsresolves its type at compile time, and it can't resolve a type parameter, soTProps & { ... }fails with "Unresolvable type reference". Addinggeneric="TProps"on its own doesn't help.The way through is
@vue-ignore:That tells the compiler to skip runtime prop generation for that type and keeps the type surface for TS, which is the part you actually want for Intellisense.
The tradeoff: only your own props get a runtime declaration. I compiled the above with
@vue/compiler-sfc