I'm currently diving into the generics feature in vue 3.3 and I've been pondering about defining the type of an incoming prop based on another prop value.
This is my current component structure:
export interface OptionProps {
id: string | number;
name: string;
};
<script setup lang="ts" generic="T extends OptionProps">
import { computed } from "vue";
import {OptionProps} from './types.ts'
// defining props using generics
const props = defineProps<{
options: T[];
modelValue: T | T[];
multiple: boolean;
}>();
// defining emits
const emit = defineEmits<{
"update:modelValue": [value: T|T[]];
}>();
// setting proxyValue for modelValue to emit update:modelValue
const proxy = computed({
get() {
return props.modelValue;
},
set(value: T|T[]) {
emit("update:modelValue", value);
},
});
</script>
<template>
<div>---- {{ options }} ----- {{ proxy }}</div>
</template>
The goal here is to limit the type of modelValue depending on the 'multiple' value, meaning:
If multiple is true -> modelValue should be T[] but if it's false, modelValue should be T
I want callers of my component to encounter an error if they try to provide an array as modelValue with multiple being false:
<script setup lang="ts">
import { ref } from 'vue'
import Comp from './Comp.vue';
import { OptionProps } from './types.ts'
const result = ref<OptionProps[]>([{id: undefined, name: undefined}])
</script>
<template>
<Comp
:model-value="result"
:options="[{id: 1, name: 'one'}, {id: 2, name: 'two'}]"
:multiple="false"
/>
</template>
I briefly considered conditional typing, but I'm unsure how to implement it in this scenario. Is it even feasible?