DEV Community

Mohd Ahmad
Mohd Ahmad

Posted on

Conditional types in typescript react

Here I am making a Button component which should render <button> or <a> conditionally, using the as prop. eg:-

// should render <button> component, prop 'as' is 'button' by default <Button> Click me </Button>  // should render <a> component  <Button as="a" href="xyz.com" > Visit here </Button> 
Enter fullscreen mode Exit fullscreen mode

The code

import React, { AnchorHTMLAttributes, ButtonHTMLAttributes, } from "react"; type Props = Partial< ButtonHTMLAttributes<HTMLButtonElement> & AnchorHTMLAttributes<HTMLAnchorElement> & { as: "a" | "button" } >; const Button: React.FC<Props> = ({ as: As = "a", ...rest }) => { return <As {...rest}></As>; }; export default Button; 
Enter fullscreen mode Exit fullscreen mode

but it is showing anchor element properties (eg: href) while as = 'button', it is not a big problem here but when I was trying to make a base component which should render as a div | main | ul | section it gives error but after removing ul it is working fine
eg

// should render <div> component  <Base as='div' /> // should render <main> component  <Base as='main' /> // should render <section> component  <Base as='section' /> // should render <ul> component  <Base as='ul' /> ^ the error part as ul props and [div | main | section] props are not matching 
Enter fullscreen mode Exit fullscreen mode

Top comments (3)

Collapse
 
benjioe profile image
Benjioe • Edited

Solution, but I thinks it's not a good idea to use {...rest} because you can add href on a button and you lost autocompletion.
Maybe you have to define all manage properties (like ant's button do)

Collapse
 
benjioe profile image
Benjioe • Edited

Why do you need a Base component instead of html tag ?

Collapse
 
mohdahmad1 profile image
Mohd Ahmad • Edited

because I dont want to repeat myself, its like I want different element but with same props

Some comments may only be visible to logged-in visitors. Sign in to view all comments.