所以我一直在使用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} />;
我必须为每个样式组件创建2个组件,这似乎相当多。
我希望我的谷歌技能只是垃圾,我错过了一些东西,除了每个样式组件的多个组件之外,还有更好的方法吗?
答案 0 :(得分:5)
是的!有一个更好的办法。诀窍是声明由样式组件创建的组件的类型。您可以通过casting https://github.com/jameskraus/flow-example-of-styled-components-props将styled.button`...`
返回的结果添加到接收所需道具的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
我在GitHub上托管了用于本地再现的代码(因为Flow的沙箱不能与外部依赖关系一起使用):Link document
答案 1 :(得分: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'};
`