tezvyn:

The polymorphic 'as' prop pattern

AI-drafted, machine-checkedSource: interviewadvanced
WHAT IT TESTS

Building reusable components with correct typing and ref forwarding.

OUTLINE

render the element from an as prop, infer props from the chosen element, and forward refs.

RED FLAG

ignoring types or dropping the ref.

WHAT THIS TESTS This question probes deep component reuse: can you build one styled component that adapts its underlying element without duplicating logic, while preserving semantics, accessibility, prop correctness, and ref forwarding?

A GOOD ANSWER COVERS The core idea is an as prop. The component reads as, defaults it to a sensible element such as button, and renders that element with the remaining props spread onto it. Use forwardRef so the consumer ref reaches the actual rendered node, not a wrapper. The hard part is typing. In TypeScript you make the component generic over the element type, then compute its valid props with ComponentPropsWithoutRef of that type, and merge them with your own props while omitting collisions. This way as equals a yields href and target, as equals button yields type and disabled, and a router Link yields its to prop, all checked at compile time.

COMMON WRONG ANSWERS Hardcoding a single element defeats the purpose. Forgetting forwardRef breaks focus management and integrations that need the node. Typing the props bag as any throws away the safety that makes polymorphism worthwhile. Spreading unknown props without merging className or style can silently clobber the component styling.

LIKELY FOLLOW-UPS How do you preserve a default element while still allowing override? How do you handle the ref type changing with as? What are the performance and bundle costs of the generic types? When should you prefer composition or asChild slot patterns instead, as Radix does with Slot?

ONE CONCRETE EXAMPLE A design system Button is normally a button, but a call to action in a card must navigate. Rendering Button with as equal to the router Link and a to prop produces an anchor with the visual button styling, keyboard and focus behavior intact, the ref forwarded for programmatic focus, and to type-checked because the props were inferred from Link.

Read the original → components.build

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.