【问题标题】:React, styled-components and TypeScript: How to wrap a styled component in a functional componentReact、样式化组件和 TypeScript:如何将样式化组件包装在功能组件中
【发布时间】:2021-04-13 22:27:01
【问题描述】:

我正在尝试为我的样式化组件创建一个包装器,但我无法正确选择类型。

假设我有一个这样的样式组件:

const Button = styled.button<ButtonProps>`
  background-color: ${(props) => props.color};
`;

现在我想创建一个包含此样式按钮的包装器组件,例如。像这样:

const WrappedButton: React.FunctionComponent<ButtonProps> = ({ children, ...rest }) => (
  <div>
    <Button {...rest}>{children}</Button>
  </div>
);

现在一切正常,但我真正想要的是WrappedButton 组件接受Button 组件将接受的所有道具并将它们传递给包装的Button 组件 .

例如,我希望编译它,因为 type 是 HTML 按钮元素的有效属性(因此也是 Button 组件的有效属性,但不是在包装 Button 组件时):

// TypeScript will throw an error because "type" is not a valid prop of WrappedButton. 
const MyComponent = () => <WrappedButton type="submit">Test</WrappedButton>

我知道我可以“键入” WrappedComponent 的道具,但这不是重点,我希望 WrappedComponent 接受普通 HTML 按钮可以接受的所有道具

编辑:我还需要包装组件上的所有样式组件特定道具,例如样式组件的as 道具。这是代码沙箱的更新版本:https://codesandbox.io/s/react-typescript-styled-components-forked-3o20j?file=/src/index.tsx

我尝试了很多东西,但 TypeScript 总是在抱怨。我也搜索了文档和互联网,但没有找到任何东西。

【问题讨论】:

    标签: reactjs typescript styled-components


    【解决方案1】:

    我相信你问的是React.ButtonHTMLAttributes&lt;HTMLButtonElement&gt;

    import React from 'react'
    import styled from 'styled-components'
    
    const Button = styled.button<ButtonProps>`
      background-color: ${(props) => props.color};
    `;
    
    
    type ButtonProps = {
    } & React.ButtonHTMLAttributes<HTMLButtonElement>;
    
    
    const WrappedButton: React.FunctionComponent<ButtonProps> = ({ children, ...rest }) => (
        <div>
            <Button {...rest}>{children}</Button>
        </div>
    );
    
    

    如果您想使用原始 html &lt;button&gt;,您可能会对以下内容感兴趣:JSX.IntrinsicElements["button"];

    查看this answer

    更新 快速而肮脏的解决方案是:

    type ButtonProps = {
    } & React.ButtonHTMLAttributes<HTMLButtonElement> & { as?: string | React.ComponentType<any> };
    

    但它不是通用的。

    SC 类型中有StyledComponentPropsWithAs 类型,但没有导出(

    【讨论】:

    • 几乎 工作,这个解决方案的唯一问题是像这样我没有包装组件上的样式组件的道具。例如,如果我将 as 属性添加到 WrappedButton,TypeScript 将无法编译。请参阅此示例:codesandbox.io/s/… 抱歉,我没有提到这是我的问题中的要求,我会相应地更新问题
    • AFAIK, as 在原始 html 按钮上不存在
    • 没错,但它存在于使用 styled.button 创建的样式组件上...我还希望包装组件接受包装样式组件的所有道具(例如as )
    • 抱歉,我在文档中找不到关于 as 属性的信息。这是您的自定义属性吗?
    • 不,这是 styled-components 的道具:styled-components.com/docs/api#as-polymorphic-prop
    猜你喜欢
    • 2020-06-03
    • 2020-10-19
    • 2021-03-08
    • 2019-10-27
    • 2019-03-13
    • 2020-09-26
    • 1970-01-01
    • 2021-11-01
    • 2019-12-30
    相关资源
    最近更新 更多