Quasar dynamic slots and Typescript

Viewed 12

I was creating a component that wraps a QInput, which passes everything down to it, but vue-tsc is complaining of the following:

 TS7053: Element implicitly has an 'any' type because expression of type 'string | number' can't be used to index type '{ default: unknown; prepend: unknown; append: unknown; before: unknown; after: unknown; label: unknown; error: unknown; hint: unknown; counter: unknown; loading: unknown; }'.
  No index signature with a parameter of type 'string' was found on type '{ default: unknown; prepend: unknown; append: unknown; before: unknown; after: unknown; label: unknown; error: unknown; hint: unknown; counter: unknown; loading: unknown; }'.

14         v-slot:[slot]="scope"
                  ~~~~~~

Component code:

<q-input
      borderless
      v-bind="$attrs"
      :model-value="props.modelValue"
    >
      <template
        v-for="(_, slot) in $slots"
        v-slot:[slot]="scope"
      >
        <slot
          :name="slot"
          v-bind="scope || {}"
        />
      </template>
    </q-input>

I was wondering if there is a workaround on this

1 Answers

Quoting my own answer from https://github.com/quasarframework/quasar/discussions/14415#discussioncomment-3667451

You can utilize the QInputSlots type by casting $slots to Readonly<QInputSlots>.

<template>
  <q-input
    borderless
    v-bind="$attrs"
    :model-value="props.modelValue"
  >
    <template
      v-for="(_, slot) in ($slots as Readonly<QInputSlots>)"
      v-slot:[slot]="scope"
    >
      <slot
        :name="slot"
        v-bind="scope || {}"
      />
    </template>
  </q-input>
</template>

<script setup lang="ts">
import type { QInputSlots } from 'quasar';

// ...
</script>

<script>
export default {
  inheritAttrs: false,
}
</script>

However, you won't get auto-completion on slot names nor get type info on template scopes. I made a comment here to see if this is expected Volar behavior: https://github.com/johnsoncodehk/volar/issues/953#issuecomment-1250029543

Related