vuejs / language-tools

⚡ High-performance Vue language tooling based-on Volar.js
https://marketplace.visualstudio.com/items?itemName=Vue.volar
MIT License
5.87k stars 400 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 3 months ago

tomvdk commented 3 months 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 3 months 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 3 months 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 2 months ago

That worked for me.

function getSlotName(name: string): `body-cell-${string}` {
  return `body-cell-${name}` as unknown as `body-cell-${string}`;
}
KermanX commented 2 months 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 2 months 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 2 months 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.