Search code examples
javascriptreactjstypescriptstyled-componentsreact-props

How to use forwardedAs prop with styled-components? Using forwardedAs prop with typescript


Here are the docs on forwardedAs prop: https://styled-components.com/docs/api#forwardedas-prop.

As you can see, it's not very detailed and does not show how to properly use this prop.

My question is: How can I access the props that are sent down via forwardedAs? How can I define types for these forwardedAs props?

I'm able to access the forwardedAs props via ...rest parameters, but I need to define types for these props since I am also using styled-components with Typescript.

Here's my code example:

// Button.jsx
const myPropsToForward = {
  href: 'https://somewebsite.com',
  // ...more props
}

const Button = styled.button`
  // ...button styles
`

const myComponent = () => (
  <Button
    as={Link}
    to={ctaLink}
    forwardedAs={myPropsToForward}
  />
)

// Link.jsx
const Link = ({
  forwardedAs,
  ...rest
}) => {
  // How do I access the forwardedAs prop from <Button /> here?

  return (
    <a href={forwardAs?.href} {...rest} />
  )
}

Here, I need to be able to access the props within the Link component sent down via forwardedAs prop, but there's no documentation on how to do that. If I can access the forwardedAs prop, I can then define proper types for the Link component. I do not want to rely on the ...rest parameter as I cannot define types for that.

Thank you in advance.


Solution

  • forwardedAs

    The forwardedAs prop is not for passing down props. It's actually for passing down an as prop to the next item in the chain. Consider this example:

    const Button = styled.button`
      padding: 20px;
    `;
    
    const Link = (props: any) => { // not properly typed
      return <Button {...props} />;
    };
    
    const MyLink = styled(Link)`
      background-color: blue;
    `
    
    const MyComponent = () => (
      <MyLink forwardedAs={"div"}>
        Text
      </MyLink>
    );
    

    We have a Button which is a styled component and we have a MyLink which is another styled component that passes its props down to the Button. If we want to set the as prop on the Button, we can set forwardedAs on MyLink.

    With <MyLink forwardedAs={"div"}>, the element that we ultimately render to the DOM is a div rather than a button and it applies the styles from both styled HOCs.

    Passing Props

    Based on your example here, the Link component is not actually needed. You can set as="a" on your Button to render it as a link and pass through myPropsToForward directly.

    const myPropsToForward = {
      href: "https://somewebsite.com"
      // ...more props
    };
    
    const Button = styled.button`
      background: yellow;
      padding: 20px;
    `;
    
    const MyComponent = () => (
      <Button as="a" {...myPropsToForward}>
        Text
      </Button>
    );