{"id":13896,"library":"react-polymorphed","title":"React Polymorphed Components","description":"react-polymorphed is a TypeScript-focused utility library designed to simplify the creation of type-safe polymorphic React components. It provides a set of types and helper functions that enable components to render as different HTML elements or other React components via an `as` prop, while maintaining strong type inference and preventing common prop errors. Currently at version 2.2.2, the library is actively maintained, with a release cadence typical for a utility focused on React type enhancements, responding to changes in React or TypeScript. Its key differentiator is the comprehensive support for `forwardRef`, `memo`, and `lazy` with polymorphic types, building on foundations laid by `react-polymorphic-types` to offer a robust and developer-friendly experience for complex component patterns.","status":"active","version":"2.2.2","language":"javascript","source_language":"en","source_url":"https://github.com/nasheomirro/react-polymorphed","tags":["javascript","react","typescript","polymoprhic-components","as-prop"],"install":[{"cmd":"npm install react-polymorphed","lang":"bash","label":"npm"},{"cmd":"yarn add react-polymorphed","lang":"bash","label":"yarn"},{"cmd":"pnpm add react-polymorphed","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency required for React type definitions, essential for type-safe polymorphic components.","package":"@types/react","optional":false}],"imports":[{"note":"Primary type for creating basic polymorphic components. Always use named import, intended for TypeScript projects.","wrong":"const PolymorphicComponent = require('react-polymorphed').PolymorphicComponent;","symbol":"PolymorphicComponent","correct":"import { PolymorphicComponent } from 'react-polymorphed';"},{"note":"A type helper for correctly casting `React.forwardRef` to support polymorphic components with ref forwarding. This is crucial for maintaining type safety for the `ref` prop across different `as` values.","symbol":"PolyRefFunction","correct":"import { PolyRefFunction } from 'react-polymorphed';"},{"note":"Use `PolyMemoComponent` for polymorphic components wrapped with `React.memo` that *do not* forward refs. If your component *does* forward refs, you must use `PolyForwardMemoComponent` instead to preserve the ref type correctly.","wrong":"import { PolyForwardMemoComponent } from 'react-polymorphed';","symbol":"PolyMemoComponent","correct":"import { PolyMemoComponent } from 'react-polymorphed';"},{"note":"A utility type for constraining the allowed values of the `as` prop. However, consider the package's FAQ as usage of `OnlyAs` might introduce more issues than benefits.","symbol":"OnlyAs","correct":"import { OnlyAs } from 'react-polymorphed';"}],"quickstart":{"code":"import React, { forwardRef, useRef } from 'react';\nimport { PolyRefFunction } from 'react-polymorphed';\n\n// Cast forwardRef to PolyRefFunction for type-safe ref forwarding in polymorphic components\nconst polyRef = forwardRef as PolyRefFunction;\n\ntype ButtonProps = {\n  size?: 'small' | 'large';\n  children: React.ReactNode;\n};\n\n// Create a polymorphic button component that supports ref forwarding\nconst Button = polyRef<'button', ButtonProps>(\n  ({ as: As = 'button', size, children, ...props }, ref) => {\n    const sizeClass = size === 'small' ? 'px-2 py-1 text-sm' : 'px-4 py-2 text-base';\n    return (\n      <As\n        ref={ref}\n        className={`bg-blue-500 text-white rounded ${sizeClass}`}\n        {...props}\n      >\n        {children}\n      </As>\n    );\n  }\n);\n\n// Example usage of the polymorphic button\nconst App = () => {\n  const buttonRef = useRef<HTMLButtonElement>(null);\n  const anchorRef = useRef<HTMLAnchorElement>(null);\n\n  return (\n    <div className=\"p-4 flex flex-col gap-4\">\n      <Button type=\"submit\" size=\"small\" ref={buttonRef}>\n        Submit Button\n      </Button>\n      <Button as=\"a\" href=\"https://example.com\" target=\"_blank\" size=\"large\" ref={anchorRef}>\n        Link to Example\n      </Button>\n      {/* This would cause a type error as 'div' does not have 'href' */}\n      {/* <Button as=\"div\" href=\"#\">Div as Link</Button> */}\n      {/* This would cause a type error due to ref mismatch */}\n      {/* <Button as=\"div\" ref={buttonRef}>Div with Button Ref</Button> */}\n    </div>\n  );\n};\n\nexport default App;\n","lang":"typescript","description":"This quickstart demonstrates how to create a ref-forwarded polymorphic `Button` component using `react-polymorphed`. It shows the casting of `forwardRef` to `PolyRefFunction`, defines component-specific props, and illustrates how the `as` prop dynamically changes the rendered element and its associated types, preventing invalid prop usage."},"warnings":[{"fix":"Before using `OnlyAs`, thoroughly review the package's FAQ section concerning constraints. Often, relying on TypeScript's natural type inference without explicit `OnlyAs` offers better flexibility and maintainability.","message":"The `OnlyAs` constraint feature, designed to restrict the `as` prop to a specific set of elements, may lead to more harm than good and is generally discouraged by the library maintainer. It could complicate type inference or prevent desired flexibility.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Always use `PolyForwardMemoComponent` for memoized ref-forwarding polymorphic components and `PolyForwardLazyComponent` for lazily loaded ones. For components without ref forwarding, use `PolyMemoComponent` or `PolyLazyComponent` respectively.","message":"When using `React.memo` or `React.lazy` with a polymorphic component that also uses `forwardRef`, it's critical to use the correct wrapper types: `PolyForwardMemoComponent` or `PolyForwardLazyComponent`. Failing to do so will result in incorrect ref type inference and potential runtime errors related to ref properties.","severity":"gotcha","affected_versions":">=2.0.0"}],"env_vars":null,"search_vec":"'2.2.2':65 'activ':69 'as-prop':134 'build':106 'cadenc':74 'chang':86 'common':59 'complex':125 'compon':3,25,37,47,126,133 'comprehens':96 'creation':18 'current':62 'design':14 'develop':121 'developer-friend':120 'differ':41 'differenti':93 'element':43 'enabl':36 'enhanc':83 'error':61 'experi':123 'focus':11,79 'forwardref':99 'foundat':108 'friend':122 'function':34 'helper':33 'html':42 'infer':56 'javascript':128 'key':92 'laid':109 'lazi':102 'librari':13,67 'maintain':53,70 'memo':100 'offer':116 'pattern':127 'polymoprh':132 'polymoprhic-compon':131 'polymorph':2,6,23,104,113 'prevent':58 'prop':51,60,136 'provid':27 'react':1,5,24,46,81,88,112,129 'react-polymorph':4 'react-polymorphic-typ':111 'releas':73 'render':39 'respond':84 'robust':118 'safe':22 'set':29 'simplifi':16 'strong':54 'support':97 'type':21,31,55,82,105,114 'type-saf':20 'typescript':10,90,130 'typescript-focus':9 'typic':75 'util':12,78 'version':64 'via':48","created_at":"2026-04-20T01:56:52.322652+00:00","updated_at":"2026-04-20T01:56:52.322652+00:00","problems":[{"fix":"Ensure that the `as` prop matches the intended HTML element that supports the given props. For `href`, set `as=\"a\"`.","cause":"Attempting to pass an `href` prop to a polymorphic component when its `as` prop is implicitly or explicitly set to a non-anchor HTML element (e.g., a `button` or `div`). The types correctly prevent invalid props for the resolved element.","error":"Type '{ href: string; }' is not assignable to type 'IntrinsicElements[\"button\"]'. Property 'href' does not exist on type 'IntrinsicElements[\"button\"]'."},{"fix":"Ensure the `ref` object's generic type matches the HTML element type specified by the `as` prop, or ensure the component specified by `as` actually supports refs. `react-polymorphed` uses `PolyRefFunction` to correctly infer the ref type based on `as`.","cause":"A `ref` type mismatch occurs when a `ref` object intended for one HTML element type (e.g., `HTMLButtonElement`) is passed to a polymorphic component rendering a different element type (e.g., `div`), or when the `as` prop points to a component that doesn't support refs.","error":"Type 'RefObject<HTMLButtonElement>' is not assignable to type 'LegacyRef<HTMLDivElement> | undefined'. Type 'RefObject<HTMLButtonElement>' is not assignable to type 'RefObject<HTMLDivElement>'. The types of 'current' are incompatible."}],"ecosystem":"npm","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":"","cli_version":null,"type":"library","homepage":null,"github":"https://github.com/nasheomirro/react-polymorphed","docs":null,"changelog":null,"pypi":null,"npm":"https://www.npmjs.com/package/react-polymorphed","openapi_spec":null,"status_page":null,"smithery":null,"categories":["web-framework"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-17","next_check":"2026-07-18","install_tag":null}}