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

Vue模板作用域插槽属性的类型推断与断言方案

在Vue TypeScript项目中为作用域插槽推断/指定类型

方案一:让组件支持泛型,自动推断插槽类型

通过给表格组件定义泛型Props,可以让组件根据传入的items类型自动推断作用域插槽的参数类型,无需手动断言。

修改AppTable.vue:

<script setup lang="ts" generic="T extends { id: number }">
// 定义泛型T,要求T必须包含id属性(匹配v-for的key需求)
defineProps<{
  items: T[];
}>();
</script>
<template>
  <table>
    <thead>
      <slot name="thead"></slot>
    </thead>
    <tbody>
      <tr v-for="(item, index) in items" :key="item.id">
        <slot name="tbody" :item="item" :index="index"></slot>
      </tr>
    </tbody>
  </table>
</template>

在App.vue中使用:

此时无需修改模板代码,当传入customers: Customer[]时,组件会自动将插槽的item类型推断为Customer,类型检查正常通过:

<script setup lang="ts">
import AppTable from './AppTable.vue';
interface Customer {
  id: number;
  name: string;
  email: string;
}
const customers: Customer[] = [
  { id: 1, name: 'John', email: 'john@example.com' },
  { id: 2, name: 'Jim', email: 'jim@example.com' },
  { id: 3, name: 'Jack', email: 'jack@example.com' },
];
</script>
<template>
  <div style="margin-bottom: 2rem">
    <app-table :items="customers">
      <template #thead>
        <th>ID</th>
        <th>Name</th>
        <th>Email</th>
      </template>
      <template #tbody="{ item: customer, index }">
        <td>{{ index + 1 }}</td>
        <td>{{ customer.name }}</td>
        <td>{{ customer.email }}</td>
      </template>
    </app-table>
  </div>
</template>

方案二:手动在模板中断言类型

如果无法修改组件(比如第三方组件),可以在模板中使用as关键字手动断言类型,绕过类型不兼容的问题:

<template #tbody="{ item: customer, index }">
  <td>{{ index + 1 }}</td>
  <td>{{ (customer as Customer).name }}</td>
  <td>{{ (customer as Customer).email }}</td>
</template>

这种方式不需要修改组件代码,但需要每次使用时手动断言,适合临时场景。

为什么原来的写法会报错?

之前尝试给插槽参数直接加类型注解的方式失败,是因为组件定义的items是unknown[],所以插槽传出的item类型是unknown。TypeScript不允许将unknown直接赋值给Customer类型(类型不安全),因此会抛出类型不兼容的错误。

而使用any虽然能解决错误,但会完全丢失类型检查,不符合TypeScript的编码规范,不推荐使用。

内容的提问来源于stack exchange,提问作者Christhofer Natalius

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 23:26:22