Vue3+TypeScript中联合类型数组渲染属性报错解决方法
解决Vue3+TypeScript联合类型渲染时的类型报错问题
你的问题核心是TypeScript无法自动收窄ToolbarItem | Divider联合类型的范围,导致模板中访问专属属性时报错。以下是两种可行的解决方法:
方法一:使用判别式联合类型(推荐)
给两个接口添加共同的type字段作为类型判别标志,让TypeScript能通过该字段自动识别具体类型:
修改父组件类型定义
// 给ToolbarItem添加type字段,标记为按钮类型 interface ToolbarItem { type: 'button'; icon: string; title: string; action: () => void; // 替换Function为具体函数类型,更严谨 isActive?: () => boolean; } // Divider的type固定为'divider' interface Divider { type: 'divider'; } const items: Array<ToolbarItem | Divider> = [ { type: 'button', // 新增type字段 icon: 'bold', title: 'Bold', action: () => props.editor.commands.toggleBold(), isActive: () => props.editor.isActive('bold'), }, { type: 'divider' }, // ...其他项 ]
模板无需修改
此时模板中的v-if="item.type === 'divider'"会自动让TypeScript识别该分支的item为Divider类型,else分支则为ToolbarItem类型,访问icon、title等属性不会再报错。
方法二:自定义类型守卫函数
如果不想修改原有类型结构,可以通过类型守卫函数手动告诉TypeScript当前item的具体类型:
父组件中添加类型守卫函数
interface ToolbarItem { icon: string; title: string; action: Function; isActive?: Function; } interface Divider { type: string; } // 判断是否为Divider类型 const isDivider = (item: ToolbarItem | Divider): item is Divider => { return (item as Divider).type === 'divider'; } const items: Array<ToolbarItem | Divider> = [ // ...原有数组项 ]
修改模板使用守卫函数
<template v-for="(item, index) in items" :key="index"> <div v-if="isDivider(item)" class="divider" :key="`divider${index}`" /> <Child v-else :key="index" :icon="item.icon" :title="item.title" :action="item.action" :isActive="item.isActive"/> </template>
类型守卫函数isDivider会让TypeScript在v-if分支确认item是Divider,else分支自动推断为ToolbarItem,从而消除属性访问报错。
内容的提问来源于stack exchange,提问作者arquirupim
相关产品推荐
相关产品推荐

