I want to implement a carousel component in Nuxt v3. This component receives a list of items. This component only implements logic, not style or structure.
Now this is my component:
Component/tdx/carousel.vue
<template> <div> <slot name="last"></slot> <div v-for="item in items"> <slot name="item" v-bind="item" ></slot> </div> <slot name="next"></slot> </div> </template> <script setup lang="ts"> const props = defineProps({ items: { type: [], required: true, }, spotlight: { type: Number, default: 1, validator(value: number) { return value > 0; }, }, }); </script>
The logic of the carousel is not important here.
In the parent component I can use the component like this:
<template> <div class="container"> <TdxCarousel :items="exampleArray"> <template #item="{ title, description }"> <p class="font-semibold text-2xl">{{ title }}</p> <hr /> <p>{{ description }}</p> </template> </TdxCarousel> </div> </template> <script setup lang="ts"> const exampleArray = ref([ { title: 'Item 1', description: 'Desc of item 1', }, { title: 'Item 2', description: 'Desc of item 2', }, ]); </script>
This works great. Other than that what I want is typing. The type of title
and description
is of course any, because in the props of carousel.vue
, the type of the item is unknown[]
.
I found this article showing how to make a generic component, but I don't want this because I have to mess with nuxt's auto-import system.
How to implement type inference from a given item in a carousel.vue
property?
Updated: May 2023
Starting from Vue 3.3, officially supports common components.
You need to define a common parameter. Modify the
carousel.vue
component to use thegeneric
tag and convert it to use type-based
defineProps
method so that it gets the generics correctly.Props on slots will now be correctly inferred based on item type.
Before May 2023
In earlier versions of VSCode/Volar, you needed to enable the Experimental flag. It requires the
experimentalRfc436
option of tsconfig.json to be enabled undervueCompilerOptions
.This is no longer necessary as it is enabled by default in recent versions of Volar.