使用带有 typescript 的样式化组件“as”prop

Posted

技术标签:

【中文标题】使用带有 typescript 的样式化组件“as”prop【英文标题】:Using styled components "as" prop with typescript 【发布时间】:2019-11-12 05:36:19 【问题描述】:

我目前正在构建一个模式库,其中我使用Reactstyled-components 构建了一个Button 组件。 基于Button 组件,我希望我的所有Links 组件看起来完全相同并接收完全相同的道具。 为此,我使用来自styled-componentsas 属性,它允许我将已构建的元素用作另一个标签或组件。

按钮组件

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 的样式化组件主题的媒体查询

使用带有Typescript的样式化组件,prop不存在?

如何在使用 TypeScript 的 create-react-app 中使用带有 babel 插件的样式化组件?

打字稿中的样式组件“as”道具和自定义道具