...

/

Mirroring and Extending the Properties of an HTML Element

Mirroring and Extending the Properties of an HTML Element

Learn how to enhance the component development by mirroring and extending the HTML element’s properties.

Creating the Button component

Let’s start with the first example. We want to create a button that comes with the appropriate styling for use in our application. In JavaScript, we might be able to do something like this:

const Button = (props) => {
return <button className="button" {...props} />;
};
Defining a Button component in JavaScript

In TypeScript, we will just add what we know and need. For example, we know that we need the children property if we want our custom button to behave the same way an HTML button does:

const Button = ({ children }: React.PropsWithChildren) => {
return <button className="button">{children}</button>;
};
Adding a Button component in TypeScript

We can imagine that adding properties one at a time could get a bit tiring. Instead, we can tell TypeScript that we want to match the same props that it would use for a <button> element in React:

const Button = (props: React.ComponentProps<'button'>) => {
return <button className="button" {...props} />;
};
Extending properties of the Button component

But we have a new problem. Or, rather, we had a problem that also existed in the JavaScript example and which we ignored. If someone using our new Button component passes in a className prop, it will override our className. We will add some code to deal with this in a moment, but we don’t want to pass up the opportunity to show how to use a utility type in TypeScript to say, “I want to use all of the props from an HTML button except for one (or more).”

type ButtonProps = Omit<React.ComponentProps<'button'>, 'className'>;
const Button = (props: ButtonProps) => {
return <button className="button" {...props} />;
};
Excluding the class from the properties of the Button component

Now, TypeScript will stop us or anyone else from passing a className property into our Button component. If we just wanted to extend the class list with whatever is passed in, we could do that in a few different ways. We could ...