使用Flow为样式组件道具

rya*_*zec 12 javascript types reactjs flowtype styled-components

所以我一直在使用JavaScript中的类型系统,并且大多数情况下工作正常但是样式组件存在问题.我似乎无法找到一种将流应用于样式组件的道具的好方法.到目前为止,我看到的唯一解决方案是:

export type ButtonPropTypes = ReactPropTypes & {
  styleType: 'safe' | 'info' | 'warning' | 'danger' | 'link',
  isPill: boolean,
  isThin: boolean,
};

export const ButtonStyled = styled.button`
  ${generateBaseStyles}
  ${hoverStyles}
  ${fillStyles}
  ${thinStyles}
  ${linkStyles}
`;

export const Button = (props: ButtonPropTypes) => <ButtonStyled {...props} />;
Run Code Online (Sandbox Code Playgroud)

我必须为每个样式组件创建2个组件似乎相当多.

我希望我的谷歌技能只是垃圾,我错过了一些东西,但除了每个样式组件的多个组件之外,还有更好的方法吗?

Jam*_*aus 5

是! 有个更好的方法。诀窍是声明由styled-components创建的组件的类型。您可以通过将返回的结果强制转换styled.button`...`采用所需prop的React组件的类型来实现。您可以使用生成使用任意属性的React组件的类型type mytype = React.ComponentType<MyProps>

// @flow
import styled from 'styled-components'
// Make sure you import with * to import the types too
import * as React from 'react'

// Mock function to use styleType
const makeStyles = ({styleType}) => ''

export type ButtonPropTypes = {
  styleType: 'safe' | 'info' | 'warning' | 'danger' | 'link',
  isPill: boolean,
  isThin: boolean,
};

export const ButtonStyled = (styled.button`
  ${makeStyles}
  ${({isPill}) => isPill ? 'display: block;' : ''}
  ${({isThin}) => isThin ? 'height: 10px;' : 'height: 100px;'}
`: React.ComponentType<ButtonPropTypes>) // Here's the cast

const CorrectUsage = <ButtonStyled styleType="safe" isPill isThin/>

const CausesError = <ButtonStyled styleType="oops" isPill isThin/> // error

const CausesError2 = <ButtonStyled styleType="safe" isPill="abc" isThin={123}/> // error
Run Code Online (Sandbox Code Playgroud)

我已经将代码托管在GitHub上以进行本地复制(因为Flow的沙箱不适用于外部依赖项):https : //github.com/jameskraus/flow-example-of-styled-components-props

  • 太棒了,您还可以使用:export const ButtonStyled:React.ComponentType &lt;ButtonPropTypes&gt; = ... (3认同)

Bra*_*ams 5

除了James Kraus的回答,如果您正在使用flow-typed(并且已经为您的版本安装了包styled-components),您基本上可以:

import styled, {type ReactComponentStyled} from 'styled-components'

type Props = {
 color?: string
}

const Button: ReactComponentStyled<Props> = styled.button`
  color: ${({color}) => color || 'hotpink'};
`
Run Code Online (Sandbox Code Playgroud)