Polymorphic components; as props
Build a polymorphic Button component with an as prop; merge intrinsic/DOM props; type refs using forwardRef and ComponentRef .
Intro
Goal: Create a single polymorphic Button that can render as button, a, or any element via an as prop—while preserving prop and ref types.
- Constrain
TtoReact.ElementType - Merge props safely
- Type the forwarded ref
Base types
Start with OwnProps and a utility PolymorphicProps<T, P> that merges intrinsic props for T with your own.
import React from "react"
type OwnProps = {
variant?: "solid" | "outline"
children: React.ReactNode
}
type PolymorphicProps<T extends React.ElementType, P> = {
as?: T
} & P & Omit<React.ComponentPropsWithoutRef<T>, keyof P | "as">
// Example: Omit avoids prop collisions (e.g., our OwnProps vs intrinsic props)