[英]Using styled components “as” prop with typescript
I'm currently building a pattern library in which I've built a Button
component using React
and styled-components
. 我目前正在构建一个模式库,其中我使用
React
和styled-components
构建了一个Button
styled-components
。 Based on the Button
component, I want all my Link
s component to look exactly the same and receive exactly the same props. 基于
Button
组件,我希望我的所有Link
组件看起来完全相同,并获得完全相同的道具。 For that purpose, I'm using the as
prop from styled-components
, which allows me to use that already built element as another tag or component. 为此,我使用
styled-components
as
prop,它允许我将已构建的元素用作另一个标记或组件。
Button Component 按钮组件
import * as React from 'react'
import { ButtonBorderAnimation } from './ButtonAnimation'
import { ButtonProps, ButtonVariant } from './Button.types'
import { ButtonBase, LeftIcon, RightIcon } from './Button.styled'
function Button({
variant = ButtonVariant.Filled,
children,
leftIcon = null,
rightIcon = null,
...props
}: ButtonProps): JSX.Element {
return (
<ButtonBase variant={variant} {...props}>
{variant !== ButtonVariant.Ghost ? (
<ButtonBorderAnimation {...props} />
) : null}
{leftIcon ? <LeftIcon>{leftIcon}</LeftIcon> : null}
{children}
{rightIcon ? <RightIcon>{rightIcon}</RightIcon> : null}
</ButtonBase>
)
}
export default Button
Button Types 按钮类型
export interface ButtonProps {
children: React.ReactNode
variant?: 'filled' | 'outlined' | 'ghost'
size?: 'small' | 'regular'
underlinedOnHover?: boolean
leftIcon?: React.ReactNode
rightIcon?: React.ReactNode
inverse?: boolean
}
export enum ButtonVariant {
Filled = 'filled',
Outlined = 'outlined',
Ghost = 'ghost',
}
export enum ButtonSize {
Small = 'small',
Regular = 'regular',
}
Link Component 链接组件
import * as React from 'react'
import Button from '../Button/Button'
import { Link as LinkRouter } from 'react-router-dom'
import { LinkProps } from './Link.types'
function Link({ to, ...props }: LinkProps): JSX.Element {
return <Button to={to} as={LinkRouter} {...props} />
}
export default Link
Link Types 链接类型
import { ButtonProps } from '../Button/Button.types'
import { LinkProps } from 'react-router-dom'
type RouterLinkWithButtonProps = ButtonProps & LinkProps
export interface LinkProps extends RouterLinkWithButtonProps {}
When I do the above, this problem comes us... 当我做上述事情时,我们遇到了这个问题......
Property 'to' does not exist on type 'IntrinsicAttributes & ButtonProps'.
...which makes sense because button doesn't have the prop to
which is required for the Link
component from react-router-dom
. ......这是有道理的,因为按钮没有道具
to
这是需要的Link
从组件react-router-dom
。
How will you approach something like this? 你将如何处理这样的事情? Where when using the
Button
the to
prop shouldn't even be in the type and when using the Link
the to
should be required. 当使用
Button
to
支柱甚至不应该在类型中,并且在使用Link
to
应该要求。
Uses 用途
<Button>Hello</Button>
<Link to="/somewhere">Hello</Link>
This should work. 这应该工作。
function Link(_props: LinkProps): JSX.Element {
const props = { as: LinkRouter, ..._props };
return <Button {...props} />
}
Note that TypeScript applies strict object literal assignment checks which can be loosened by assigning an object literal to a variable beforehand instead of directly passing it as, for example, an function argument, which is consistent with the React component props assignment behavior. 请注意,TypeScript应用严格的对象文字赋值检查 ,可以通过事先将对象文字分配给变量而不是直接将其作为例如函数参数传递来放松,该函数参数与React组件props赋值行为一致。
declare function foo(arg: { a: number }): void;
foo({ to: '', a: 1 }); // error
const arg = { to: '', a: 1 };
foo(arg); // no error
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.