You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 22:12:38