ismail9k / vue3-carousel

Vue 3 carousel component
https://ismail9k.github.io/vue3-carousel/
MIT License
715 stars 172 forks source link

Typescript support for ref() #392

Open nexorianus opened 1 week ago

nexorianus commented 1 week ago

I dont know if this is a bug or a feature request.

Describe the bug Currently there seems to be no way to set up the ref for the Carousel component in a typesafe way.

To have editors add typings and intellisense to the ref we would need to add a type to it.

As far as I know, there is no type to add to the ref to get the correct typings as const carousel = ref<CarouselElement>(null);

To Reproduce Steps to reproduce the behavior:

  1. Add the <Carousel> to a components template part
  2. Add a ref to the carousel component: <Carousel ref="carousel">
  3. Add the ref to the script setup part: const carousel = ref(null)
  4. Try to access any of the carousels properties/functions in script-setup. Typing of the ref is (property) Ref<null>.value: null image
  5. Also in template the functions typings say Property 'prev' does not exist on type 'never'. image

What I tried to get around this:

import type { Carousel } from 'vue3-carousel';
const carousel = ref<Carousel>();
//                   --------
// --> 'Carousel' refers to a value, but is being used as a type here. Did you mean 'typeof Carousel'?
import type { Carousel } from 'vue3-carousel';
const carousel = ref<typeof Carousel>();
const curSlide = computed(() => carousel.value?.data?.currentSlide ?? 0);
//                                                    ------------
// --> Property 'currentSlide' does not exist on type '(this: CreateComponentPublicInstance<...>, vm: CreateComponentPublicInstance<Readonly<ExtractPropTypes<{ itemsToShow: { default: number; type: NumberConstructor; }; itemsToScroll: { default: number; type: NumberConstructor; }; wrapAround: { default: boolean | undefined; type: BooleanConstructor; }; ... 11 more ...; ...'.

Additional Info

I am trying to use this in a nuxt@3 environment with the "vue3-carousel-nuxt" wrapper

Expected behavior

vue3-carousel exports a typeing to be used with refs to be typesafe.

TheKvikk commented 1 week ago

Since this library doesn't come with correct typings – missing component's exposed instance properties – you have to define it yourself. I'm using this

<script setup lang="ts">
import { Carousel } from 'vue3-carousel';

type CarouselConfig = InstanceType<typeof Carousel>['$props']; // optional, use any
type CarouselExpose = {
  updateBreakpointsConfigs: () => void;
  updateSlidesData: () => void;
  updateSlideWidth: () => void;
  initDefaultConfigs: () => void;
  restartCarousel: () => void;
  slideTo: (slideIndex: number) => void;
  next: () => void;
  prev: () => void;
  nav: {
    slideTo: (slideIndex: number) => void;
    next: () => void;
    prev: () => void;
  };
  data: {
    config: CarouselConfig;
    slidesCount: Ref<number>;
    slideWidth: Ref<number>;
    next: () => void;
    prev: () => void;
    slideTo: (slideIndex: number) => void;
    currentSlide: Ref<number>;
    maxSlide: Ref<number>;
    minSlide: Ref<number>;
    middleSlide: Ref<number>;
  };
};

const carouselRef = ref<CarouselExpose | null>();
</script>

<template>
  <Carousel ref="carouselRef">
    ...
  </Carousel>
</template>
nexorianus commented 6 days ago

Thank you @TheKvikk this is a good workaround.

i will be leaving this ticket open, since I think this should be included in the repo, instead of needing to manually add it to the project.