react-tinder-card icon indicating copy to clipboard operation
react-tinder-card copied to clipboard

How to type useRef?

Open BBartt opened this issue 3 years ago • 8 comments

Hi I have typescript app and I want to add buttons like in https://github.com/3DJakob/react-tinder-card/blob/master/index.js here. The problem is that I can not properly type useRef hook to use swipe() method.

const tinderCardRef = useRef(null); tinderCardRef.current.swipe();

Thanks

BBartt avatar Nov 30 '21 18:11 BBartt

Hi,

you are dealing most probably with an array therefore you have to do the following thing:

// init childRefs

  // set refs for swiping cards with button
  const childRefs: RefObject<API>[] = useMemo(
    () =>
      Array(yourArray)
        .fill(0)
        .map((i) => createRef()),
    [yourArray],
  );

// init fn for swipe for example with buttons

  // swipe function
  const swipe = async (direction: Direction) => {
    if (
      canSwipe &&
      currentIndex < yourArray.length &&
      childRefs[currentIndex].current
    ) {
      await childRefs[currentIndex].current.swipe(direction); // Swipe the card!
    }
  };

// ref on TinderCard

 ref={childRefs[index]}

For more details check this example, you can easily see how to deal with it: https://github.com/3DJakob/react-tinder-card-demo/blob/master/src/examples/Advanced.js

skusebauch avatar May 24 '22 13:05 skusebauch

I had this same issue. I think it would help a lot of API and Direction were exported from the library. I had to use some typescript magic to expose them.

seeker-3 avatar Jun 01 '22 18:06 seeker-3

@seeker-3 - what sort of magic did you use? I've resorted to going into the package folder and manually exporting them

robertjawoods avatar Jun 20 '22 17:06 robertjawoods

I started off trying to do some magic

import type TinderCard from 'react-tinder-card'

type ExtractGenericFromRefObject<TRefObject> =
  TRefObject extends RefObject<infer U> ? U : never

type TinderCardProps = Parameters<typeof TinderCard>[0]
export type API = ExtractGenericFromRefObject<TinderCardProps['ref']>

Which successfully extracted the type, but for some reason, it would fuss at me when I tried importing the API type into another file, so I just found their type declarations and pasted them into my file 🤢.

type Direction = 'left' | 'right' | 'up' | 'down'

export interface API {
  swipe(dir?: Direction): Promise<void>
  restoreCard(): Promise<void>
}

seeker-3 avatar Jun 22 '22 00:06 seeker-3

I started off trying to do some magic

import type TinderCard from 'react-tinder-card'

type ExtractGenericFromRefObject<TRefObject> =
  TRefObject extends RefObject<infer U> ? U : never

type TinderCardProps = Parameters<typeof TinderCard>[0]
export type API = ExtractGenericFromRefObject<TinderCardProps['ref']>

Which successfully extracted the type, but for some reason, it would fuss at me when I tried importing the API type into another file, so I just found their type declarations and pasted them into my file 🤢.

type Direction = 'left' | 'right' | 'up' | 'down'

export interface API {
  swipe(dir?: Direction): Promise<void>
  restoreCard(): Promise<void>
}

Fair enough mate I don't blame you there, thanks :)

robertjawoods avatar Jun 22 '22 01:06 robertjawoods

same issue, please fix. wasted time on this.

sgehrman avatar Sep 30 '22 02:09 sgehrman

The fact that critical types are not exposed is a red flag for this library. The necessary work that needs to be done is to go through the whole library and change things here and there to follow typescript best practices, and then also refactor the example library to use typescript with zero eslint errors/warnings on the strictest settings feasible

Johnrobmiller avatar Dec 18 '22 02:12 Johnrobmiller

With npmjs libraries, you take what you can get. Expecting libraries to have clean code is a bit foolish, better to just be thankful it exists at all! 🙏

Johnrobmiller avatar Dec 18 '22 02:12 Johnrobmiller