I am trying to create a generic component where a user can pass the a custom OptionType to the component to get type checking all the way through. This componen
Creating a generic component as output of React.forwardRef is not directly possible1 (see bottom for further info). There are some alternatives though - let's simplify your example a bit for illustration:
type Option = {
value: O;
label: string;
}
type Props> = { options: T[] }
const options = [
{ value: 1, label: "la1", flag: true },
{ value: 2, label: "la2", flag: false }
] // just some options data
// Given input comp for React.forwardRef
const FRefInputComp = (props: Props, ref: Ref) =>
{props.options.map(o => {o.label}
)}
// Cast the output
const FRefOutputComp1 = React.forwardRef(FRefInputComp) as
(p: Props & { ref?: Ref }) => ReactElement
const Usage11 = () =>
// options has type { value: number; label: string; flag: boolean; }[]
// , so we have made FRefOutputComp generic!
This works, as the return type of forwardRef in principle is a plain function. We just need a generic function type shape. You could an extra type to make the assertion simpler:
type ForwardRefFn = (p: P & React.RefAttributes) => ReactElement | null
// RefAttributes is built-in with ref and key props defined
const Comp12 = React.forwardRef(FRefInputComp) as ForwardRefFn
const Usage12 = () =>
const FRefOutputComp2 = React.forwardRef(FRefInputComp)
// T is replaced by its constraint Option in FRefOutputComp2
export const Wrapper = ({myRef, ...rest}:
Props & {myRef: React.Ref}) =>
const Usage2 = () =>
This one is my favorite - simplest alternative, a legitimate way in React and doesn't use forwardRef.
const Comp3 = (props: Props & { myRef: Ref }) =>
{props.options.map(o => {o.label}
)}
const Usage3 = () =>
1 The type declaration of React.forwardRef is:
function forwardRef(render: ForwardRefRenderFunction): ...
So it takes a generic component-like interface, whose type parameters T, P must be concrete. In other words: ForwardRefRenderFunction is not a generic function declaration, so higher order function type inference cannot propagate free type parameters on to the calling function React.forwardRef.
Playground