Impersonate Native DOM Elements with React Components and TypeScript for Full Reusability

Shawn Wang
InstructorShawn Wang
Share this video with your friends

Social Share Links

Send Tweet
Published 5 years ago
Updated 3 years ago

Individually defining props doesn't scale especially if you are wrapping native DOM elements, for example for the purpose of building up a Design System. Fortunately, there are easy strategies to lend full TypeScript support to your custom React elements, without excessive typing.

Instructor: [00:03] Let's say I've been making my React and TypeScript app and I've been using a native dom element for a while. Then I decide to make a reusable component to add some extra features, for example, a label property.

[00:19] Here I've defined a label prop, and I've used it as my text. I decide to swap out my small-b button for my large-b custom button and specify my label inside a prop instead of in the native button.

[00:39] This refactoring works. Maybe this is the start of my new design system. However, the problem comes in when I start to want to use the other properties of a button.

[00:53] For example, if I wanted to pass in custom styles, and for example, I wanted to make styling to have a border of five-px-solid-green and I passed it in here, that would not work because style is not a declared prop of button.

[01:19] One way to resolve this is to add a style prop explicitly declared. I can declare inside my prop. I can add a style. It will be optional. I can say it takes React.css properties. Now I can apply the style to props. Style equals to props.style.

[01:44] The problem is that this approach doesn't scale. The button inherits properties and attributes from the general HTML interface, the HTML attributes, as well as the specific button element interface. All of those things can be looked up in index.d.ts inside of your node modules, inside of @types/reactindex.t.ts.

[02:13] You could conceivably refactor to spread your props, but that still leaves the task of laboriously defining every single prop that a button has on top of your synthetic button. What you really want to have is all of the base properties of the button element, which you can copy and paste.

[02:41] Then for the remaining props that you want to continue to add, you can just use an intersection type. That resolves both your custom properties, as well as the general other properties that are required as well.

[02:59] For example, on-click is defined neatly without needing to define it manually yourself.

egghead
egghead
~ 6 minutes ago

Member comments are a way for members to communicate, interact, and ask questions about a lesson.

The instructor or someone from the community might respond to your question Here are a few basic guidelines to commenting on egghead.io

Be on-Topic

Comments are for discussing a lesson. If you're having a general issue with the website functionality, please contact us at support@egghead.io.

Avoid meta-discussion

  • This was great!
  • This was horrible!
  • I didn't like this because it didn't match my skill level.
  • +1 It will likely be deleted as spam.

Code Problems?

Should be accompanied by code! Codesandbox or Stackblitz provide a way to share code and discuss it in context

Details and Context

Vague question? Vague answer. Any details and context you can provide will lure more interesting answers!

Markdown supported.
Become a member to join the discussionEnroll Today