使用带有 typescript 的样式化组件“as”prop
Posted
技术标签:
【中文标题】使用带有 typescript 的样式化组件“as”prop【英文标题】:Using styled components "as" prop with typescript 【发布时间】:2019-11-12 05:36:19 【问题描述】:我目前正在构建一个模式库,其中我使用React
和styled-components
构建了一个Button
组件。
基于Button
组件,我希望我的所有Link
s 组件看起来完全相同并接收完全相同的道具。
为此,我使用来自styled-components
的as
属性,它允许我将已构建的元素用作另一个标签或组件。
按钮组件
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
按钮类型
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',
链接组件
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
链接类型
import ButtonProps from '../Button/Button.types'
import LinkProps from 'react-router-dom'
type RouterLinkWithButtonProps = ButtonProps & LinkProps
export interface LinkProps extends RouterLinkWithButtonProps
当我执行上述操作时,这个问题就来了……
Property 'to' does not exist on type 'IntrinsicAttributes & ButtonProps'.
...这是有道理的,因为按钮没有 to
所需的 react-router-dom
组件中的 Link
组件。
您将如何处理这样的事情?当使用 Button
时,to
属性甚至不应该在类型中,而在使用 Link
时,to
应该是必需的。
用途
<Button>Hello</Button>
<Link to="/somewhere">Hello</Link>
【问题讨论】:
为什么不将button
组件定义为内部有一个Link
?在你的文件../Button/Button
?
是否可以展示您的button
实现?那样会更容易回答。
@its4zahoor 添加了问题中的按钮实现。
@its4zahoor 你第一条评论的答案是:我想分别对待它们,但仍然有相同的风格和道具。这更像是一种打字稿问题,而不是反应问题。
这可能会给一些想法medium.com/dailyjs/…
【参考方案1】:
这应该可行。
function Link(_props: LinkProps): JSX.Element
const props = as: LinkRouter, ..._props ;
return <Button ...props />
请注意,TypeScript 应用 strict object literal assignment checks 可以通过预先将对象文字分配给变量而不是直接将其作为例如函数参数传递来放松,这与 React 组件 props 分配行为一致。
declare function foo(arg: a: number ): void;
foo( to: '', a: 1 ); // error
const arg = to: '', a: 1 ;
foo(arg); // no error
【讨论】:
以上是关于使用带有 typescript 的样式化组件“as”prop的主要内容,如果未能解决你的问题,请参考以下文章
带有 Typescript 和样式化组件的 RN FlatList
带有 Typescript 和 ThemeProvider 的样式化组件。啥是正确的类型?
包括对带有 typescript 的样式化组件主题的媒体查询