react-native-animatable icon indicating copy to clipboard operation
react-native-animatable copied to clipboard

How to use Animatable.View in Typescript

Open matheuspelegrino opened this issue 4 years ago • 16 comments

Code:


import * as Animatable from 'react-native-animatable';

const Connection: React.FC = () => {
  const animatableRef = useRef<Animatable.View>(null);
// not working
// const animatableRef = useRef<Animatable.View | null>(null);
// const animatableRef = useRef<Animatable.View | null>();
// const animatableRef = useRef<Animatable.View>();
 
   [...] 
  return (
    <Animatable.View
      ref={animatableRef}
      animation="slideInDown"
      style={{ zIndex: 10 }}
    >
      
        <Text>Say hello</Text>
   
    </Animatable.View>
  );
};

Error in ref property


No overload matches this call.
  Overload 1 of 2, '(props: AnimatableProperties<ViewStyle> & ViewProps, context?: any): ClassicComponent<AnimatableProperties<ViewStyle> & ViewProps, any>', gave the following error.
    O tipo 'RefObject<View>' não pode ser atribuído ao tipo 'string | ((instance: ClassicComponent<AnimatableProperties<ViewStyle> & ViewProps, any> | null) => void) | RefObject<...> | null | undefined'.
      O tipo 'RefObject<View>' não pode ser atribuído ao tipo 'RefObject<ClassicComponent<AnimatableProperties<ViewStyle> & ViewProps, any>>'.
        Type 'AnimatableComponent<ViewProps, ViewStyle>' is missing the following properties from type 'ClassicComponent<AnimatableProperties<ViewStyle> & ViewProps, any>': replaceState, isMounted, context, setState, and 4 more.
  Overload 2 of 2, '(props: AnimatableProperties<ViewStyle> & ViewProps, context?: any): Component<AnimatableProperties<ViewStyle> & ViewProps, any, any>', gave the following error.
    O tipo 'RefObject<View>' não pode ser atribuído ao tipo 'string | ((instance: Component<AnimatableProperties<ViewStyle> & ViewProps, any, any> | null) => void) | RefObject<Component<AnimatableProperties<...> & ViewProps, any, any>> | null | undefined'.
      O tipo 'RefObject<View>' não pode ser atribuído ao tipo 'RefObject<Component<AnimatableProperties<ViewStyle> & ViewProps, any, any>>'.
        Type 'AnimatableComponent<ViewProps, ViewStyle>' is missing the following properties from type 'Component<AnimatableProperties<ViewStyle> & ViewProps, any, any>': context, setState, forceUpdate, render, and 2 more.ts(2769)
index.d.ts(145, 9): The expected type comes from property 'ref' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes<ClassicComponent<AnimatableProperties<ViewStyle> & ViewProps, any>> & Readonly<...> & Readonly<...>'
index.d.ts(145, 9): The expected type comes from property 'ref' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes<Component<AnimatableProperties<ViewStyle> & ViewProps, any, any>> & Readonly<...> & Readonly<...>'

matheuspelegrino avatar May 11 '20 02:05 matheuspelegrino

I also came across this issue.

I removed the type and it works


const Connection: React.FC = () => {
  const animatableRef = useRef(null);

  return (
    <Animatable.View
      ref={animatableRef}
      animation="slideInDown"
      style={{ zIndex: 10 }}
    >
      
        <Text>Say hello</Text>
   
    </Animatable.View>
  );
}

I have faith in TypeScript's type inference that I don't need to explicitly define the type.

Edit

Completely ignore me, it just returns a RefType<any> or something along those lines. I was wrong about the type inference!

andrico1234 avatar May 11 '20 08:05 andrico1234

Not sure if its the best solution, but I find the following works well:

const animatableRef = useRef<Animatable.View & View>(null);

matt-pawley avatar May 11 '20 16:05 matt-pawley

Awesome, it worked @toughdeveloper!

In theory, it doesn't have to be necessary, does it?

Animatable.View returns or must reference a View Props:

export type View = AnimatableComponent <ViewProperties, ViewStyle>; 

Or am I wrong?

matheuspelegrino avatar May 11 '20 16:05 matheuspelegrino

@toughdeveloper solution worked for me.

However, when using it with custom components doesn't seem to work. I am trying to use it with react-native-fast-image anyone know how I should be doing it?

const AnimatedImage = Animatable.createAnimatableComponent(FastImage);

const imageRef = React.useRef<typeof AnimatedImage>(null);
No overload matches this call.
  Overload 1 of 2, '(props: AnimatableProperties<StyleProp<ImageStyle>> & FastImageProperties, context?: any): ClassicComponent<AnimatableProperties<StyleProp<ImageStyle>> & FastImageProperties, any>', gave the following error.
    Type 'RefObject<AnimatableComponent<FastImageProperties, StyleProp<ImageStyle>>>' is not assignable to type 'string | ((instance: ClassicComponent<AnimatableProperties<StyleProp<ImageStyle>> & FastImageProperties, any> | null) => void) | RefObject<...> | null | undefined'.
      Type 'RefObject<AnimatableComponent<FastImageProperties, StyleProp<ImageStyle>>>' is not assignable to type 'RefObject<ClassicComponent<AnimatableProperties<StyleProp<ImageStyle>> & FastImageProperties, any>>'.
        Type 'AnimatableComponent<FastImageProperties, StyleProp<ImageStyle>>' is missing the following properties from type 'ClassicComponent<AnimatableProperties<StyleProp<ImageStyle>> & FastImageProperties, any>': replaceState, isMounted, context, setState, and 4 more.
  Overload 2 of 2, '(props: AnimatableProperties<StyleProp<ImageStyle>> & FastImageProperties, context?: any): Component<AnimatableProperties<StyleProp<ImageStyle>> & FastImageProperties, any, any>', gave the following error.
    Type 'RefObject<AnimatableComponent<FastImageProperties, StyleProp<ImageStyle>>>' is not assignable to type 'string | ((instance: Component<AnimatableProperties<StyleProp<ImageStyle>> & FastImageProperties, any, any> | null) => void) | RefObject<...> | null | undefined'.
      Type 'RefObject<AnimatableComponent<FastImageProperties, StyleProp<ImageStyle>>>' is not assignable to type 'RefObject<Component<AnimatableProperties<StyleProp<ImageStyle>> & FastImageProperties, any, any>>'.
        Type 'AnimatableComponent<FastImageProperties, StyleProp<ImageStyle>>' is missing the following properties from type 'Component<AnimatableProperties<StyleProp<ImageStyle>> & FastImageProperties, any, any>': context, setState, forceUpdate, render, and 2 more.ts(2769)
index.d.ts(145, 9): The expected type comes from property 'ref' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes<ClassicComponent<AnimatableProperties<StyleProp<ImageStyle>> & FastImageProperties, any>> & Readonly<...> & Readonly<...>'
index.d.ts(145, 9): The expected type comes from property 'ref' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes<Component<AnimatableProperties<StyleProp<ImageStyle>> & FastImageProperties, any, any>> & Readonly<...> & Readonly<...>'

ryoid avatar May 19 '20 16:05 ryoid

Same with using custom animations. Type error on the animation property.

<Animatable.Image 
  animation={{ 
    from: { rotateY: '0deg' }, 
    to: { rotateY: '359deg'} 
   }}
   />

probablykabari avatar Jun 01 '20 15:06 probablykabari

Any update on this issue?

darron1217 avatar Nov 25 '20 04:11 darron1217

@toughdeveloper solution worked for me.

However, when using it with custom components doesn't seem to work. I am trying to use it with react-native-fast-image anyone know how I should be doing it?

const AnimatedImage = Animatable.createAnimatableComponent(FastImage);

const imageRef = React.useRef<typeof AnimatedImage>(null);

@ryoid I was having a similar issue, although I'm using react-native-reanimated (version 2.2.0) and what I'm doing is a bit different. I managed to fix the error by casting the FastImage:

const AnimatedFastImage = Animated.createAnimatedComponent(
    FastImage as ComponentClass<FastImageProps, unknown>
);

This is the error I was getting:

No overload matches this call.
  Overload 1 of 2, '(component: ComponentClass<FastImageProps, any>, options?: Options<FastImageProps> | undefined): ComponentClass<AnimateProps<FastImageProps>, any>', gave the following error.
    Argument of type 'ComponentType<FastImageProps> & FastImageStaticProperties' is not assignable to parameter of type 'ComponentClass<FastImageProps, any>'.
      Type 'FunctionComponent<FastImageProps> & FastImageStaticProperties' is not assignable to type 'ComponentClass<FastImageProps, any>'.
        Type 'FunctionComponent<FastImageProps> & FastImageStaticProperties' provides no match for the signature 'new (props: FastImageProps, context?: any): Component<FastImageProps, any, any>'.
  Overload 2 of 2, '(component: FunctionComponent<FastImageProps>, options?: Options<FastImageProps> | undefined): FunctionComponent<AnimateProps<FastImageProps>>', gave the following error.
    Argument of type 'ComponentType<FastImageProps> & FastImageStaticProperties' is not assignable to parameter of type 'FunctionComponent<FastImageProps>'.
      Type 'ComponentClass<FastImageProps, any> & FastImageStaticProperties' is not assignable to type 'FunctionComponent<FastImageProps>'.
        Type 'ComponentClass<FastImageProps, any> & FastImageStaticProperties' provides no match for the signature '(props: PropsWithChildren<FastImageProps>, context?: any): ReactElement<any, any> | null'.ts(2769)

So I cast the FastImage as the type that the parameter seemed to be expecting.

isghanim avatar Oct 06 '21 22:10 isghanim

  const OptionsAnimationRef = React.useRef<Animatable.View>();

Seems to be working but when I am trying

  OptionsAnimationRef.current?.slideInLeft(300);

I have

  Cannot invoke an object which is possibly 'undefined'.ts(2722)

Anyone knows how to fix this ?

dennisbouwpas avatar Oct 25 '21 15:10 dennisbouwpas

I have been using type casting with React.RefObject<T> so far and it works.

const Comp = () => {
	const animatableViewRef = useRef() as React.RefObject<Animatable.View & View>;

	React.useEffect(() => {
		if (
			animatableViewRef.current &&
			typeof animatableViewRef.current.bounceIn === 'function'
		) {
			animatableViewRef.current.bounceIn(1000);
		}
	}, []);

	return <Animatable.View>{/* ... */}</Animatable.View>;
};

alielmajdaoui avatar Dec 01 '21 21:12 alielmajdaoui

any updates?

betopompolo avatar Nov 10 '22 19:11 betopompolo

I'm doing this and it's an ugly solution:

// from another file so I can reuse it
export type AnimatableViewRef = Animatable.View & View;

// on my component
const viewRef = useRef<AnimatableViewRef>(null);

useEffect(() => {
  if (focused) {
    viewRef.current?.zoomIn?.(1000);
  } else {
    viewRef.current?.zoomOut?.(1000);
  }
}, [focused]);

We should have an AnimatableViewRef type properly typed.

In my case, there is no time that zoomIn and zoomOut are undefined if the viewRef.current is not undefined, so we should not have to check zoomIn?.(n) in runtime.

marioteik avatar Oct 15 '23 13:10 marioteik

Also noticing the TS error that @dennisbouwpas is seeing. Using typescript 5.1.3.

pachun avatar Mar 12 '24 19:03 pachun