vuejs / language-tools

⚡ High-performance Vue language tooling based-on Volar.js
https://marketplace.visualstudio.com/items?itemName=Vue.volar
MIT License
5.55k stars 373 forks source link

[bug] The behavior of 'slotName' typescript is inconsistent between Vue 2.7 and Vue 3 when use generic #4439

Closed Kanade-Lu closed 3 weeks ago

Kanade-Lu commented 3 weeks ago

minimal reproducible project:

version:

What is expected?

slotName #testSlot should not error, #[name] should be extends by interface ITest

What is actually happening?

The property "testSlot" does not exist on type "{ lastColumns?(_: { props: any; row: any; index: any; }): any; }".

<script setup lang="ts" generic="T">
import type { ITableColumnConfig } from './types';

defineProps<{
  tableColumnConfig: ITableColumnConfig<T>[]
}>()
</script>

<template>
  <div>
    <el-table>
      <el-table-column v-for="item in tableColumnConfig">
        <!-- #correct -->
        <!-- <slot :name="item.prop" /> -->

        <!-- #correct -->
        <!-- <template #default="tableRow">
          <slot :name="item.prop" />
        </template> -->

        <!-- #correct -->
        <!-- <div v-if="item.onClick"></div>
        <div v-else>
          <slot :name="item.prop" />
        </div> -->

        <!-- #error -->
        <template v-if="item.onClick" #default="tableRow"></template>
        <template v-else #default="tableRow">
          <slot :name="item.prop" />
        </template>

      </el-table-column>
      <el-table-column label="操作" align="center">
        <template #default="tableRow">
          <slot name="lastColumns" :props="tableRow" :row="tableRow.row" :index="tableRow.$index" />
        </template>
      </el-table-column>

    </el-table>
  </div>
</template>
<!-- Test.vue -->
<template>
    <div>
      <LxJsonTable
        :table-column-config="tableColumnConfig"
      > 
        <!-- #error, but should not error, lose all slotName type -->
        <template #testSlot>
        </template>
        <template #lastColumns></template>
      </LxJsonTable>
    </div>
  </template>

  <script setup lang="ts">
  import LxJsonTable from './Component.vue'
  import type { ITableColumnConfig } from './types';

  interface ITest {
    orderId: string;
    testSlot: string;
    redeemInfo: {
      test: string;
    }
    goods: {
      test: string;
      title: string;
    }
    coverImage:  {
      uploadImage: string;
    }
    price: string
  }
  const tableColumnConfig: ITableColumnConfig<ITest>[] = []
  </script>