When defining a generic Vue component, it appears that the resulting type of the generic is the union of all arguments. Is it possible to limit this so the type of all properties must match?
For example, a generic select component:
<script setup lang="ts" generic="T extends string">
// We want to enforce modelValue & options come from the same set of possible values
defineProps<{
modelValue?: T
options: readonly T[]
}>()
const emit = defineEmits<(e: 'update:modelValue', val?: T) => void>()
// Have a <select with options
</script>
I would hope that with the above component, I would get an error with the below usage as the two types being passed do not intersect
<script setup lang="ts">
type ValidOptions = "Big"|"Small"|"Medium"
const value = ref<ValidOptions>("Small")
</script>
<template>
<!-- options & modelValue have different types here -->
<MySelect :options="['Chicken','Little'] as const" v-model="value" />
</template
However, when defining it in this way the generic type ends up being the union of all types: "Chicken"|"Little"|"Big"|"Small"|"Medium"
, and so no error is reported
You can type your select like this:
<component :is="MySelect<ValidOptions>" :options="['Chicken','Little'] as const" v-model="value" />