meliorence / react-native-snap-carousel

Swiper/carousel component for React Native featuring previews, multiple layouts, parallax images, performant handling of huge numbers of items, and more. Compatible with Android & iOS.
BSD 3-Clause "New" or "Revised" License
10.37k stars 2.29k forks source link

renderItem typescript error with item unknown #754

Open kickbk opened 4 years ago

kickbk commented 4 years ago

Really love this snap carousel. I'm having an issue where I get TypeScript error on renderItem.

import MealCarousel from 'react-native-snap-carousel';

const RestaurantListRow: React.FC<Restaurant> = React.memo(
  (item) => {
    const {
      ...
      meals,
    } = item;
    const renderItem = React.useCallback(
      ({ item, index }: { item: Meal; index: number }) => {
        return (
          <TouchableWithoutFeedback
            onPress={() => ...}>
            <RestaurantMeal meal={item} />
          </TouchableWithoutFeedback>
        );
      },
      [meals, ...]
    );
return(
  ...
  <MealCarousel
    data={meals}
    renderItem={renderItem}
    sliderWidth={width}
    itemWidth={width - 30}
    removeClippedSubviews={false}
  />
...

I am importing meals, which is a Meal[] that cannot contain unknown objects. When I hover on top of item in the render function, I can see the item is of type Meal.

The full error I am getting is:

Type '({ item }: { item: Meal; }) => JSX.Element' is not assignable to type '((baseData: { index: number; dataIndex: number; item: unknown; }, parallaxData: { scrollPosition: Value | undefined; carouselRef: ScrollView | FlatList<unknown> | null; vertical: false; itemWidth: number; sliderWidth: number; }) => ReactNode) | ((baseData: { ...; }, parallaxData: { ...; }) => ReactNode)'.
  Type '({ item }: { item: Meal; }) => JSX.Element' is not assignable to type '(baseData: { index: number; dataIndex: number; item: unknown; }, parallaxData: { scrollPosition: Value | undefined; carouselRef: ScrollView | FlatList<unknown> | null; vertical: false; itemWidth: number; sliderWidth: number; }) => ReactNode'.
    Types of parameters '__0' and 'baseData' are incompatible.
      Type '{ index: number; dataIndex: number; item: unknown; }' is not assignable to type '{ item: Meal; }'.
        Types of property 'item' are incompatible.

However, if I simple render a snap carousel using an simple array of items from a local file, then I don't get this error.

What am I doing wrong?

I should also mention that when I run tsc I am getting an error for the typescript definition file of the library as well and for renderItem as well:

node_modules/react-native-snap-carousel/lib/typescript/carousel/types.d.ts:58:5
    58     renderItem: (baseData: {
           ~~~~~~~~~~
    The expected type comes from property 'renderItem' which is declared here on type '(IntrinsicAttributes & IntrinsicClassAttributes<Carousel<unknown>> & Pick<Readonly<CarouselBaseProps<unknown> & HorizontalCarouselProps<...> & Pick<...>> & Readonly<...>, "data" | ... 18 more ... | "renderItem"> & Partial<...> & Partial<...>) | (IntrinsicAttributes & ... 3 more ... & Partial<...>)'
ajacquierbret commented 4 years ago

Hey ! Check this : https://github.com/archriss/react-native-snap-carousel/pull/678#issuecomment-693518137

dohooo commented 3 years ago

Sorry, please allow me to advertise for my open source library! ~ I think this library react-native-reanimated-carousel will solve your problem. It is a high performance and very simple component, complete with React-Native reanimated 2

MatkoMilic commented 2 years ago

Having same issues.

I-am-abdulazeez commented 10 months ago

Still having issues in 2024

I-am-abdulazeez commented 10 months ago

The Documentation needs to use Typecript and functional component.

yanoyuki commented 5 days ago

I also encountered the similar error when wrapping a functional component with memo, but the following method worked for me.

type Item = {
   id: number
   text: string
}

const ITEMS: Item[] = [
  ...
]

type Props = { item: Item; index: number };

const Item = memo(({ item }: Props) => {
  return <Text>id: {item.id}, title: {item.title}</Text>
});

...

<Carousel
  layout="default"
  data={ITEMS}
  renderItem={(props: ItemProps) => <Item {...props} />}
  ...
/>