如何为组件键入样式属性以接受数组?

Rob*_*zak 4 javascript typescript reactjs react-native

在 React Native 中,视图元素接受一个style在驼峰式对象中使用 CSS 属性名称的属性:

const styleObj = {
  width: 200,
  marginTop: 10
}
Run Code Online (Sandbox Code Playgroud)

元素也接受这样的样式对象数组:

<MyComponent style={[ styleObj, styleProp && styleProp ]} />
Run Code Online (Sandbox Code Playgroud)

我有几个抽象的按钮组件,它们依赖于共享的基本按钮界面。为简单起见:

interface IButton {
  style?: ViewStyle | ViewStyle[] // <-- ViewStyle is exported by react native, and contains all the allowed style properties for a View component
}
Run Code Online (Sandbox Code Playgroud)

我认为这个定义就足够了,但我遇到了一些我难以理解的问题。

我有一个DropDown组件,它呈现一个Button. 当我使用 style 道具时,我收到一个错误:

<Button
  style={[
    {
      backgroundColor: backgroundColor || COLORS.lightRed,
      borderRadius: 3,
      height: 44,
      width: '100%',
     },
     style && style, // <-- type is ViewStyle | ViewStyle[], this is passed in as a prop
  ]}
Run Code Online (Sandbox Code Playgroud)

以上抛出错误:

Type (ViewStyle | ViewStyle[] | undefined)[] is not assignable to ViewStyle | ViewStyle[] | undefined
Run Code Online (Sandbox Code Playgroud)

如果我铸造风格:style && (style as ViewStyle)我得到一个不同的错误:

Type (ViewStyle | undefined)[] is not assignable to ViewStyle[]
Run Code Online (Sandbox Code Playgroud)

如果我将整个数组转换为一个ViewStyle错误清除:

<Button
  style={[
    {
      backgroundColor: backgroundColor || COLORS.lightRed,
      borderRadius: 3,
      height: 44,
      width: '100%',
     },
     style && style,
  ] as ViewStyle}
Run Code Online (Sandbox Code Playgroud)

这很好,但我有点困惑。我有一种预感,因为我的组件使用相同的 props 接口,TypeScript 变得混乱了。最终我不确定为什么会发生这些错误,以及我需要依赖强制转换的定义有什么不正确的地方。

Rob*_*zak 5

As obvious as this should have been, it took me a while to find the best solution.

When typing your style props, use ViewStyle, TextStyle etc (instead of StyleProp<T>), and when passing an array of styles simply use Stylesheet.flatten() to silence any type incompatibilities:

<Button
  style={Stylesheet.flatten([
    {
      backgroundColor: backgroundColor || COLORS.lightRed,
      borderRadius: 3,
      height: 44,
      width: '100%',
     },
     style && style,
  ])}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,使用“StyleSheet.flatten()”会删除反应本机样式表优化 (3认同)