简体   繁体   English

使用Flow为样式组件道具

[英]Using Flow for styled-components Props

So I have been playing around with type systems in JavaScript and for the most part things are working however there is an issue with styled-components. 所以我一直在使用JavaScript中的类型系统,并且大多数情况下工作正常但是样式组件存在问题。 I can't seem to find a good way to apply flow to the props of a styled-component. 我似乎无法找到一种将流应用于样式组件的道具的好方法。 So far the only solution I see is: 到目前为止,我看到的唯一解决方案是:

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} />;

It seems pretty excessive that I have to create 2 component for every styled component. 我必须为每个样式组件创建2个组件似乎相当多。

I am hoping my google skills are just crap and I am missing something but is there a better way to do this other than multiple components per styled component? 我希望我的谷歌技能只是垃圾,我错过了一些东西,但除了每个风格的组件多个组件之外,还有更好的方法吗?

Yes! 是! There is a better way. 有一个更好的办法。 The trick is to declare the type of the component created by styled-components. 诀窍是声明由样式组件创建的组件的类型。 You can do this by casting the result returned by styled.button`...` to the type of a React component that takes in your desired props. 您可以通过将styled.button`...`返回的结果转换为接收所需道具的React组件的类型来完成此操作。 You can generate the type of a React component that takes in arbitrary props with type mytype = React.ComponentType<MyProps> . 您可以生成一个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

I've hosted the code on GitHub for local reproduction (since Flow's sandbox doesn't work with external dependencies): https://github.com/jameskraus/flow-example-of-styled-components-props 我已经在GitHub上托管了用于本地再现的代码(因为Flow的沙箱不能与外部依赖关系一起工作): https//github.com/jameskraus/flow-example-of-styled-components-props

In addition to James Kraus' answer, if you're using flow-typed (and have installed the package for your version of styled-components ) you can essentially: 除了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'};
`

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM