This article assumes you are familiar with basic TypeScript & React
Imagine you wanted a React component that just spits out a native HTML button. That’s simple, You could do this
const Button = props => {
const { children } = props
return <button {...props}>{children}</button>
}If the project is large and more long-term, there’s a chance you’re using TypeScript. Your code might look like this
interface ButtonProps {
...
}
const Button: FC<ButtonProps> = (props) => {
const {children} = props
return <button>{children}</button>
}Using your Component cannot be any easier
<Button>I'm a Button</Button>The Problem
We should be able to pass in attributes of a native HTML button, like styles, onClick, etc. But here’s what happens when we try to
This is because our fancy Button element has no knowledge it’s rendering a native button element.
The Solution
TypeScript gives us a way to extend attributes for native HTML elements. I’ve seen a lot of ways to do this, but DOMAttributes<HTMLButtonElement> and HTMLAttributes<HTMLButtonElement> seem to be the most used. Here’s some example
interface ButtonProps extends DOMAttributes<HTMLButtonElement> {}
or
interface ButtonProps extends HTMLAttributes<HTMLButtonElement> {}So What Should I Use?
If you look into the TypeScript declaration file for React (node_modules/react/react.d.ts), you’ll find this line of code
interface HTMLAttributes<T> extends AriaAttributes, DOMAttributes<T> {...}This makes it clear which you should use now; HTMLAttributes is DOMAttributes plus AriaAttributes.
Thanks for reading😊