TypeScript环境下如何正确为Vue插槽props设置类型
Vue 插槽 Props 的 TypeScript 类型标注问题
问题场景
开发表格组件时为插槽props设置TypeScript类型,相关代码场景如下:
尝试过的写法均未达到预期:
#body={item: UserItem}:该写法只会触发Vue插槽的参数重命名逻辑,不会生效类型标注#body={<UserItem>item}、#body={item<UserItem>}:不符合语法规则,完全无法生效
正确标注方案
根据使用场景可以选择以下几种写法:
- 单属性快速断言
适合只需要给单个解构出的参数标注类型的场景,直接用TS的as关键字做类型断言即可:
<template #body="{ item }"> <span>{{ (item as UserItem).userName }}</span> </template>
- 插槽作用域整体标注
需要给多个插槽参数统一标注类型时,可以直接给整个插槽props对象加类型注解,注意参数列表需要包裹在括号中:
<template #body="slotProps: { item: UserItem, index: number }"> <span>第{{ slotProps.index }}个用户:{{ slotProps.item.userName }}</span> </template>
- 提前声明插槽类型(推荐)
Vue 3.3及以上版本支持通过defineSlots宏在script中提前声明插槽的入参类型,模板中使用时会自动推导类型,不需要重复标注:
<script setup lang="ts"> // 先定义数据类型 interface UserItem { id: number userName: string } // 声明插槽类型 defineSlots<{ body: (scope: { item: UserItem; index: number }) => void }>() </script> <template> <!-- 这里解构出的item、index会自动推导对应类型 --> <template #body="{ item, index }"> <span>第{{ index }}个用户:{{ item.userName }}</span> </template> </template>
注意:Vue SFC模板中的插槽语法有专属的TS扩展规则,不要直接套用TSX的泛型标注写法,否则会被模板编译器识别为普通属性/重命名逻辑。
内容的提问来源于stack exchange,提问作者Mauricio Loya
相关产品推荐
相关产品推荐

