Vue 3 动态插槽导致 vue-tsc 上出现错误 TS2339

问题描述 投票:0回答:1

我在 vue 3 (3.5.8) typescript 项目中有一个选项卡组件。这些选项卡接受一个名为

nav
的道具,它可能看起来像这样:

const nav = ref([
        {
            id: 'about',
            name: 'About',
        },
        {
            id: 'enquire',
            name: 'Enquire',
        },
    ])

对于每个导航项,我们都会生成一个

slot
,其中包含简单的内容顺序命名系统。

<div v-if="nav" class="tabs-content">
    <div
        v-for="(tab, index) in nav"
        :id="tab.id"
        :key="index"
        <slot :name="`tab${index + 1}`"></slot>
    </div>
</div>

给我们 tab1 和 tab2 插槽。这意味着我们可以像这样填充选项卡内容:

<template #tab1></template>

但是在运行构建命令时,vue-tsc 抛出错误:

错误 TS2339:类型“TabsSlots”上不存在属性“tab1”。

vue 文档有一个关于此的部分,但不是很深入: https://vuejs.org/api/sfc-script-setup.html#defineslots 我对此的所有尝试均不成功。

我已确保 typescript、vue、vue-tsc 包都是最新的

到目前为止,我的所有方法都是尝试根据 nav 属性注册动态插槽,这与创建插槽本身的方式相同。

有人有办法解决这个问题吗?我在 StackOverflow 上找不到有关此特定问题的任何内容,并且 AI 工具似乎正在努力解决 DefineSlots 作为一项新功能的问题。

在此处查看 Vue SFC Playground 演示

typescript vuejs3 vite vuejs-slots vue-tsc
1个回答
0
投票

尝试使用通用 Tab[] 类型并将其用于 props 和 slot。不要忘记将

as const
添加到
nav
:

游乐场

<script lang="ts" setup generic="const Tabs extends Readonly<Tab[]>">
  import { ref } from 'vue'

  export interface Tab {
        id: string
        name: string
    }

  const selected = ref('about')
  
  const $slots = defineSlots<{
        [K in Exclude<Exclude<keyof Tabs | `${Tabs['length']}`, keyof []>, '0'> as `tab${K & string}`]: () => void
    }>();
    
  const props = withDefaults(
        defineProps<{
            nav?: Tabs
        }>(),
        {
            nav: undefined,
        }
    )
</script>
© www.soinside.com 2019 - 2024. All rights reserved.