Animated.View的样式道具的打字稿定义

时间:2018-07-25 14:47:18

标签: typescript react-native typescript-typings

我有一个组件,其Props接口从React Native扩展了ViewProps,即:

export interface Props extends ViewProps {
  // Custom props
}

自然,这扩展了style道具。有一个警告,我正在使用Animated.View并且具有这样的样式:

style={{
  opacity: animationCharacter.interpolate({
    inputRange: [0, 1],
    outputRange: [0, 1]
  }),
  transform: [
    {
      scale: animationCharacter.interpolate({
        inputRange: [0, 1],
        outputRange: [1.2, 1]
      })
    }
  ]
}}

我认为interpolate调用与ViewProps中的样式输入不兼容,但是我无法扩展AnimatedViewProps

这里是否有解决方案,还是我必须设置style: any

6 个答案:

答案 0 :(得分:5)

@types/react-native v0.61.9开始,您可以使用Animated.AnimatedProps

例如样式道具:

interface Props {
  style?: Animated.AnimatedProps<StyleProp<ViewStyle>>,
}

或者获取所有道具:

export interface Props extends Animated.AnimatedProps<ViewProps> {
  // Custom props
}

答案 1 :(得分:2)

我不相信有内置的解决方案。看着the type definitions for React Native,Animated命名空间甚至没有指定Animated组件的类型,并且just leaves them as any

/**
 * Animated variants of the basic native views. Accepts Animated.Value for
 * props and style.
 */
export const View: any;
export const Image: any;
export const Text: any;
export const ScrollView: any;

即使React Native源(使用FlowType)也将道具留在plain Object type

class AnimatedComponent extends React.Component<Object> {
  …
}

这可能是因为React Native具有包装器类,用于内部专门处理动画stylesprops(甚至是transforms),这使得由于抽象而难以精确地指定类型。我认为您最好的选择是使用any,因为创建您自己的类型非常繁琐,而且几乎没有好处。

答案 2 :(得分:0)

我制作了“种类”类型,可以将任何视图样式转换为可设置动画的样式。

type MaybeAnimated<T> = T | Animated.Value;
type AnimatedScalar = string | number;

type AnimatedStyles<T> = {
  [Key in keyof T]: T[Key] extends AnimatedScalar
    ? MaybeAnimated<T[Key]>
    : T[Key] extends Array<infer U>
    ? Array<AnimatedStyles<U>>
    : AnimatedStyles<T[Key]>
};

type ViewAnimatedStyles = AnimatedStyles<ViewStyle>;

const test: ViewAnimatedStyles = {
  transform: [
    {
      rotateY: new Animated.Value(2),
    }
  ]
}

您会获得自动建议,并且动画值会起作用。

限制: Animated.Value的定义只是空类,因此从技术上讲,所有内容都将与之匹配。这样您就可以为其分配一个不正确的值(例如,纯字符串而不是数字)

详细了解推断和条件类型:https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html

答案 3 :(得分:0)

//从“ react-native”导入{Animated}

interface ImageComponentProps {
  height: Animated.Value;
  width: Animated.Value;
  opacity: Animated.Value;
  uri: string;
}

这对我有用!

答案 4 :(得分:0)

对于我来说,像这样的类型定义就可以了:

 const scaleValue = new Animated.Value( 0 );
 const cardScale: Animated.Mapping = scaleValue.interpolate( {
    inputRange: [0, 0.5, 1],
    outputRange: [1, .95, .9],
  } );
 const transformStyle = {transform: [{scale: cardScale}]};
<TouchableWithoutFeedback
  onPressIn={ () => {
    scaleValue.setValue( 0 );
    Animated.timing( scaleValue, {
      toValue: 1,
      duration: 60,
      easing: Easing.lenear
    } ).start();
   } }

   onPressOut={ () => {
    Animated.timing( scaleValue, {
      toValue: 0,
      duration: 550,
      easing: Easing.bounce,
    } ).start();
   } }
>
  <Animated.View style={ transformStyle }>
    {// some stuff}
  </Animated.View>
</TouchableWithoutFeedback>

答案 5 :(得分:0)

React-Native库已经为此提供了一些帮助:

import { Animated } from "react-native";

type AnimatedViewStyle = WithAnimatedValue<ViewStyle>;