vuejs / language-tools

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

Dynamic slot name Template error: Type 'QTableSlots' has no matching index signature for type 'string'.ts-plugin(2537) #4668

Closed tomvdk closed 1 month ago

tomvdk commented 1 month ago

Vue - Official extension or vue-tsc version

2.0.28

VSCode version

1.91.1

Vue version

3.4.29

TypeScript version

5.4.5

System Info

No response

Steps to reproduce

As of version 2.0.28 of Vue Official, we get the following syntax highlighting if we use a dynamic slot name. In this case it is for QTableSlots of the Quasar Component Library.

<template #[`body-cell-${actionsKey}`]="data">

image

What is expected?

No syntax highlighting as described in https://vuejs.org/guide/components/slots.html#dynamic-slot-names

What is actually happening?

Syntax highlighting and error in Problems window. When using Vue Official 2.0.26 this error does not occur.

Link to minimal reproduction

No response

Any additional comments?

No response

davidmatter commented 1 month ago

Regression from https://github.com/vuejs/language-tools/pull/4478

Test case

main.vue

<template>
  <Child>
    <template #[`action${n}`]="data">
      {{ exactType(data.a, {} as string) }}
    </template>
    <template #[`action2`]="data">
      {{ exactType(data.a, {} as string) }}
    </template>
  </Child>
</template>
<script lang="ts" setup>
import { exactType } from 'tsc/shared'
import Child from './child.vue'

const n = 1 as const
</script>

child.vue

<template></template>

<script lang="ts" setup>
defineSlots<{
  action1: (props: { a: string }) => void
  action2: (props: { a: string }) => void
}>()
</script>
KermanX commented 1 month ago

Opened #4669 for the type problem.

About the syntax highlighting problem, I think the current behavior is expected:

  1. IMO, syntax highlighting should be as error-tolerant as possible
  2. complex expression is actually supported in SFC: example
dmichaelnm commented 1 month ago

That worked for me.

function getSlotName(name: string): `body-cell-${string}` {
  return `body-cell-${name}` as unknown as `body-cell-${string}`;
}
KermanX commented 1 month ago

That worked for me.

function getSlotName(name: string): `body-cell-${string}` {
  return `body-cell-${name}` as unknown as `body-cell-${string}`;
}

This can be simplified to:

function getSlotName(name: string) {
  return `body-cell-${name}` as const;
}
tomvdk commented 1 month ago

That worked for me.

function getSlotName(name: string): `body-cell-${string}` {
  return `body-cell-${name}` as unknown as `body-cell-${string}`;
}

This can be simplified to:

function getSlotName(name: string) {
  return `body-cell-${name}` as const;
}

This works fine! Thanks!

tomvdk commented 4 weeks ago

After 2.1.0 release this is now fixed. No need for the workaround above anymore.

<template #[body-cell-${actionsKey}]="data"> works fine now.