基于联合类型声明的组件Props如何设置不同默认值?
为Vue联合类型Props设置不同默认值的解决方案
当组件Props基于联合类型声明时,直接使用withDefaults无法实现为不同分支设置专属默认值——不仅会触发TypeScript类型错误,还会导致默认值互相覆盖。以下是可行的解决思路:
核心思路
利用联合类型的判别式字段(这里是name),在组件内部根据字段值区分Props分支,再分别合并对应分支的默认值,既能满足类型校验,又能避免默认值覆盖。
方案1:使用计算属性处理
<script setup lang="ts"> import { defineProps, computed } from 'vue'; interface PropsA { name: 'a', option?: 'x' | 'y', } interface PropsB { name: 'b', option?: 'y' | 'z', otherOption?: boolean, } type ComponentProps = PropsA | PropsB; const props = defineProps<ComponentProps>(); // 根据name字段合并对应默认值 const mergedProps = computed(() => { if (props.name === 'a') { return { option: 'x', // PropsA的默认值 ...props, } as PropsA; } else { return { option: 'z', // PropsB的option默认值 otherOption: true, // PropsB的otherOption默认值 ...props, } as PropsB; } }); </script>
方案2:直接在setup中处理
如果不需要响应式,也可以直接在setup函数内完成默认值合并:
<script setup lang="ts"> import { defineProps } from 'vue'; interface PropsA { name: 'a', option?: 'x' | 'y', } interface PropsB { name: 'b', option?: 'y' | 'z', otherOption?: boolean, } type ComponentProps = PropsA | PropsB; const props = defineProps<ComponentProps>(); let processedProps: PropsA | PropsB; if (props.name === 'a') { processedProps = { option: 'x', ...props }; } else { processedProps = { option: 'z', otherOption: true, ...props }; } </script>
原方案错误原因
withDefaults要求默认值的类型必须符合所有联合分支的交集类型:
- PropsA的
option类型是'x'|'y',PropsB的option类型是'y'|'z',两者的交集只有'y',无法同时兼容'x'和'z'作为默认值; - 展开两个默认值对象时,后一个对象的
option会覆盖前一个,导致逻辑和类型都不符合预期。
内容的提问来源于stack exchange,提问作者user9434015
相关产品推荐
相关产品推荐

