Saturday, May 17, 2025
News PouroverAI
Visit PourOver.AI
No Result
View All Result
  • Home
  • AI Tech
  • Business
  • Blockchain
  • Data Science & ML
  • Cloud & Programming
  • Automation
  • Front-Tech
  • Marketing
  • Home
  • AI Tech
  • Business
  • Blockchain
  • Data Science & ML
  • Cloud & Programming
  • Automation
  • Front-Tech
  • Marketing
News PouroverAI
No Result
View All Result

Creating Polymorphic Components in TypeScript

October 11, 2023
in Cloud & Programming
Reading Time: 3 mins read
0 0
A A
0
Share on FacebookShare on Twitter


In this quick tip, excerpted from Unleashing the Power of TypeScript, Steve shows you how to use polymorphic components in TypeScript.

In my article Extending the Properties of an HTML Element in TypeScript, I told you that, over the course of building out a large application, I tend to end up making a few wrappers around components. Box is a primitive wrapper around the basic block elements in HTML (such as <div>, <aside>, <section>, <article>, <main>, <head>, and so on). But just as we don’t want to lose all the semantic meaning we get from these tags, we also don’t need multiple variations of Box that are all basically the same. What we’d like to do is use Box but also be able to specify what it ought to be under the hood. A polymorphic component is a single adaptable component that can represent different semantic HTML elements, with TypeScript automatically adjusting to these changes.

Here’s an overly simplified take on a Box element inspired by Styled Components.

And here’s an example of a Box component from Paste, Twilio’s design system:

<Box as=”article” backgroundColor=”colorBackgroundBody” padding=”space60″>
Parent box on the hill side
<Box
backgroundColor=”colorBackgroundSuccessWeakest”
display=”inline-block”
padding=”space40″
>
nested box 1 made out of ticky tacky
</Box>
</Box>

Here’s a simple implementation that doesn’t have any pass through any of the props, like we did with Button and LabelledInputProps above:

import { PropsWithChildren } from ‘react’;

type BoxProps = PropsWithChildren<{
as: ‘div’ | ‘section’ | ‘article’ | ‘p’;
}>;

const Box = ({ as, children }: BoxProps) => {
const TagName = as || ‘div’;
return <TagName>{children}</TagName>;
};

export default Box;

We refine as to TagName, which is a valid component name in JSX. That works as far a React is concerned, but we also want to get TypeScript to adapt accordingly to the element we’re defining in the as prop:

import { ComponentProps } from ‘react’;

type BoxProps = ComponentProps<'div'> & {
as: ‘div’ | ‘section’ | ‘article’ | ‘p’;
};

const Box = ({ as, children }: BoxProps) => {
const TagName = as || ‘div’;
return <TagName>{children}</TagName>;
};

export default Box;

I honestly don’t even know if elements like <section> have any properties that a <div> doesn’t. While I’m sure I could look it up, none of us feel good about this implementation.

But what’s that ‘div’ being passed in there and how does it work? If we look at the type definition for ComponentPropsWithRef, we see the following:

type ComponentPropsWithRef = T extends new (
props: infer P,
) => Component
? PropsWithoutRef

& RefAttributes>
: PropsWithRef>;

We can ignore all of those ternaries. We’re interested in ElementType right now:

type BoxProps = ComponentPropsWithRef<'div'> & {
as: ElementType;
};

Okay, that’s interesting, but what if we wanted the type argument we give to ComponentProps to be the same as … as?

We could try something like this:

import { ComponentProps, ElementType } from ‘react’;

type BoxProps = Omit, ‘as’> & {
as?: E;
};

const Box = ({ as, …props }: BoxProps) => {
const TagName = as || ‘div’;
return <TagName {…props} />;
};

export default Box;

Now, a Box component will adapt to whatever element type we pass in with the as prop.

A Box with the props of a button

We can now use our Box component wherever we might otherwise use a <div>:

<Box as=”section” className=”flex place-content-between w-full”>
<Button className=”button” onClick={decrement}>
Decrement
</Button>
<Button onClick={reset}>Reset</Button>
<Button onClick={increment}>Increment</Button>
</Box>

You can see the final result on the polymorphic branch of the GitHub repo for this tutorial.

This article is excerpted from Unleashing the Power of TypeScript, available on SitePoint Premium and from ebook retailers.



Source link

Tags: ComponentsCreatingPolymorphicTypeScript
Previous Post

Understanding Intersection Over Union for Object Detection (Code) | by Kiprono Elijah Koech | Oct, 2023

Next Post

Unleashing the Power of the Julia SuperType | by Emma Boudreau | Oct, 2023

Related Posts

Top 20 Javascript Libraries You Should Know in 2024
Cloud & Programming

Top 20 Javascript Libraries You Should Know in 2024

June 10, 2024
Simplify risk and compliance assessments with the new common control library in AWS Audit Manager
Cloud & Programming

Simplify risk and compliance assessments with the new common control library in AWS Audit Manager

June 6, 2024
Simplify Regular Expressions with RegExpBuilderJS
Cloud & Programming

Simplify Regular Expressions with RegExpBuilderJS

June 6, 2024
How to learn data visualization to accelerate your career
Cloud & Programming

How to learn data visualization to accelerate your career

June 6, 2024
BitTitan Announces Seasoned Tech Leader Aaron Wadsworth as General Manager
Cloud & Programming

BitTitan Announces Seasoned Tech Leader Aaron Wadsworth as General Manager

June 6, 2024
Copilot Studio turns to AI-powered workflows
Cloud & Programming

Copilot Studio turns to AI-powered workflows

June 6, 2024
Next Post
Unleashing the Power of the Julia SuperType | by Emma Boudreau | Oct, 2023

Unleashing the Power of the Julia SuperType | by Emma Boudreau | Oct, 2023

Where to Watch Frasier Reboot in 2023 [StreamFrom Anywhere]

Where to Watch Frasier Reboot in 2023 [StreamFrom Anywhere]

UPDATE 2-Microsoft says US has asked for $28.9 billion in audit dispute

UPDATE 2-Microsoft says US has asked for $28.9 billion in audit dispute

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

  • Trending
  • Comments
  • Latest
Is C.AI Down? Here Is What To Do Now

Is C.AI Down? Here Is What To Do Now

January 10, 2024
Porfo: Revolutionizing the Crypto Wallet Landscape

Porfo: Revolutionizing the Crypto Wallet Landscape

October 9, 2023
23 Plagiarism Facts and Statistics to Analyze Latest Trends

23 Plagiarism Facts and Statistics to Analyze Latest Trends

June 4, 2024
A Complete Guide to BERT with Code | by Bradney Smith | May, 2024

A Complete Guide to BERT with Code | by Bradney Smith | May, 2024

May 19, 2024
Part 1: ABAP RESTful Application Programming Model (RAP) – Introduction

Part 1: ABAP RESTful Application Programming Model (RAP) – Introduction

November 20, 2023
Saginaw HMI Enclosures and Suspension Arm Systems from AutomationDirect – Library.Automationdirect.com

Saginaw HMI Enclosures and Suspension Arm Systems from AutomationDirect – Library.Automationdirect.com

December 6, 2023
Can You Guess What Percentage Of Their Wealth The Rich Keep In Cash?

Can You Guess What Percentage Of Their Wealth The Rich Keep In Cash?

June 10, 2024
AI Compared: Which Assistant Is the Best?

AI Compared: Which Assistant Is the Best?

June 10, 2024
How insurance companies can use synthetic data to fight bias

How insurance companies can use synthetic data to fight bias

June 10, 2024
5 SLA metrics you should be monitoring

5 SLA metrics you should be monitoring

June 10, 2024
From Low-Level to High-Level Tasks: Scaling Fine-Tuning with the ANDROIDCONTROL Dataset

From Low-Level to High-Level Tasks: Scaling Fine-Tuning with the ANDROIDCONTROL Dataset

June 10, 2024
UGRO Capital: Targeting to hit milestone of Rs 20,000 cr loan book in 8-10 quarters: Shachindra Nath

UGRO Capital: Targeting to hit milestone of Rs 20,000 cr loan book in 8-10 quarters: Shachindra Nath

June 10, 2024
Facebook Twitter LinkedIn Pinterest RSS
News PouroverAI

The latest news and updates about the AI Technology and Latest Tech Updates around the world... PouroverAI keeps you in the loop.

CATEGORIES

  • AI Technology
  • Automation
  • Blockchain
  • Business
  • Cloud & Programming
  • Data Science & ML
  • Digital Marketing
  • Front-Tech
  • Uncategorized

SITEMAP

  • Disclaimer
  • Privacy Policy
  • DMCA
  • Cookie Privacy Policy
  • Terms and Conditions
  • Contact us

Copyright © 2023 PouroverAI News.
PouroverAI News

No Result
View All Result
  • Home
  • AI Tech
  • Business
  • Blockchain
  • Data Science & ML
  • Cloud & Programming
  • Automation
  • Front-Tech
  • Marketing

Copyright © 2023 PouroverAI News.
PouroverAI News

Welcome Back!

Login to your account below

Forgotten Password? Sign Up

Create New Account!

Fill the forms bellow to register

All fields are required. Log In

Retrieve your password

Please enter your username or email address to reset your password.

Log In