import { ComponentProps, ElementType, forwardRef, ForwardRefRenderFunction, } from 'react'; export type As = ElementType; // type Test = As<{ prop: string }> export type PropsWithAs< Props = Record, Type extends As = As > = Props & Omit, 'as' | keyof Props> & { as?: Type; }; // type Test = PropsWithAs<{ prop: string }, As<{ prop2: string }>>["as"]; // type Test = PropsWithAs<{ prop: string }, As<{ prop2: string }>>["prop"]; // type Test = PropsWithAs<{ prop: string }, As<{ prop2: string }>>["prop2"]; // type Test = PropsWithAs<{ prop: string }, "a">["as"]; // type Test = PropsWithAs<{ prop: string }, "a">["href"]; export type ComponentWithAs = { ( props: PropsWithAs & { as: Type } ): JSX.Element; (props: PropsWithAs): JSX.Element; }; // type Test = ComponentWithAs<{ prop: string }, "button">; // -------------------- // UTILS // -------------------- export function forwardRefWithAs( component: ForwardRefRenderFunction ) { return (forwardRef(component) as unknown) as ComponentWithAs< Props, DefaultType >; }