0 day streak
javascript / expert
Snippet

Type-Safe Polymorphic Components with Dynamic Tags

Polymorphic components can change their underlying HTML element (e.g., a Button acting as an 'a' tag) while keeping full TypeScript support for the corresponding attributes.

snippet.js
javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
type ButtonProps<T extends React.ElementType> = {
as?: T;
children: React.ReactNode;
} & React.ComponentPropsWithoutRef<T>;
function Button<T extends React.ElementType = 'button'>({
as,
children,
...props
}: ButtonProps<T>) {
const Component = as || 'button';
return <Component {...props}>{children}</Component>;
}
react
Breakdown
1
T extends React.ElementType = 'button'
Uses generics to capture the type of the element being passed, defaulting to 'button'.
2
React.ComponentPropsWithoutRef<T>
Automatically inherits all valid HTML attributes for the specific tag being used.
3
const Component = as || 'button'
Assigns the dynamic tag to a capitalized variable so JSX treats it as a component.