diff --git a/src/index.ts b/src/index.ts
index 0338099..8751b21 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -38,6 +38,7 @@ export * from './lifecycle/hooks/useIsMountedState/useIsMountedState.js';
export * from './lifecycle/hooks/useMount/useMount.js';
export * from './lifecycle/hooks/useUnmount/useUnmount.js';
export * from './nextjs/useIsomorphicLayoutEffect/useIsomorphicLayoutEffect.js';
+export * from './types/PolymorphicComponentProps/PolymorphicComponentProps.js';
export * from './utils/adjustFontSize/adjustFontSize.js';
export * from './utils/arrayRef/arrayRef.js';
export * from './utils/createTimeout/createTimeout.js';
diff --git a/src/types/PolymorphicComponentProps/PolymorphicComponentProps.mdx b/src/types/PolymorphicComponentProps/PolymorphicComponentProps.mdx
new file mode 100644
index 0000000..d2a0e99
--- /dev/null
+++ b/src/types/PolymorphicComponentProps/PolymorphicComponentProps.mdx
@@ -0,0 +1,85 @@
+import { Meta } from '@storybook/blocks';
+
+
+
+# PolymorphicComponentProps
+
+A collection of generic types to help build strongly typed Polymorphic Components, consistently.
+
+`PolymorphicComponentProps` takes care of combining your Component's unique prop types with those of
+any HTML element or React Component you happen to be assigning to your Polymorphic Component. As an
+extra precaution, a check is performed to omit any "default" prop type from the chosen element that
+might conflict with one of the same name in your Component.
+
+## Usage
+
+```tsx
+type FooComponentProps = PolymorphicComponentProps<
+ T,
+ { barProp: string | undefined }
+>;
+
+type FooComponent = (props: FooComponentProps) => ReactNode | null;
+
+export const Foo: FooComponent = ({
+ as: Component = 'div',
+ children,
+ ...otherProps
+}: FooComponentProps) => {
+ return {children};
+};
+```
+
+The type `FooComponentProps` consists of `T` and any custom prop types you require for
+`` (in this example, `barProp`). The types for `T` are derived from the element in
+the `as` prop:
+
+```tsx
+
+ This is a proper link
+
+
+
+ Foo as a heading: anything goes.
+
+```
+
+So while two examples use the same FooComponent, their `FooComponent` types are not the same. They
+are derived from the types from their respective `` and `` elements.
+
+```tsx
+
+ This button will throw an error
+
+
+ console.log("Clicked")}>
+ This button is okay
+
+```
+
+### Using Refs
+
+A Polymorphic Component with Refs can be typed with `PolymorphicComponentPropsWithRef` and
+`PolymorphicRef`:
+
+```tsx
+type FooComponentProps = PolymorphicComponentPropsWithRef<
+ T,
+ { barProp: string | undefined }
+>;
+
+type FooComponent = (props: FooComponentProps) => ReactNode | null;
+
+export const Foo: FooComponent = forwardRef(
+ (
+ { as: Component = 'div', children, ...otherProps }: FooComponentProps,
+ ref?: PolymorphicRef,
+ ) => {
+ return (
+
+ {children}
+
+ );
+ },
+);
+```
diff --git a/src/types/PolymorphicComponentProps/PolymorphicComponentProps.ts b/src/types/PolymorphicComponentProps/PolymorphicComponentProps.ts
new file mode 100644
index 0000000..f4126b0
--- /dev/null
+++ b/src/types/PolymorphicComponentProps/PolymorphicComponentProps.ts
@@ -0,0 +1,31 @@
+import type {
+ ComponentPropsWithoutRef,
+ ComponentPropsWithRef,
+ ElementType,
+ PropsWithChildren,
+} from 'react';
+
+/**
+ * PropsFromAs is a type based on the supplied as prop.
+ */
+type PropsFromAs = { as?: Type };
+
+/**
+ * MergeAndOverride is a type that omits type keys from BaseTypes that are also present in OverrideProps.
+ */
+type MergeAndOverride = Omit &
+ OverrideProps;
+
+export type PolymorphicRef = ComponentPropsWithRef['ref'];
+
+export type PolymorphicComponentProps<
+ BaseType extends ElementType,
+ OwnProps = Record,
+> = PropsWithChildren<
+ MergeAndOverride, PropsFromAs & OwnProps>
+>;
+
+export type PolymorphicComponentPropsWithRef<
+ BaseType extends ElementType,
+ OwnProps = Record,
+> = PolymorphicComponentProps & { ref?: PolymorphicRef };