Skip to content
Advertisement

Typescript: How to type ForwardRefExoticComponent + ComponentType

I am trying to type a Component prop that could accept both:

const MyInput = RN.TextInput

As well as something more custom:

const MyInput = React.forwardRef<RN.TextInput, RN.TextInputProps>(textProps: RN.TextInputProps) =>
<RN.View>
  <RN.TextInput {...props} />
</RN.View>

So, I tried:

const MyComp = (props: {
  MyInput: React.ComponentType<RN.TextInputProps>
}) => ...

But when trying to set a ref, I get:

const MyComp = ({ MyInput }) => {
  const ref = React.useRef<InputText>()
  return <MyInput ref={ref}
}

/*
Type '{ ref: RefObject<TextInput>; style: { height: number; fontSize: number; lineHeight: number; }; selectTextOnFocus: true; value: string; onChangeText: (text: string) => void; multiline: true; onKeyPress: (e: NativeSyntheticEvent<...>) => void; onSubmitEditing: () => void; onCancelEditing: () => void; }' is not assignable to type 'IntrinsicAttributes & TextInputProps & { children?: ReactNode; }'.
  Property 'ref' does not exist on type 'IntrinsicAttributes & TextInputProps & { children?: ReactNode; }'.ts(2322)
*/

Then I tried:

const MyComp = (props: {
  MyInput: React.ForwardRefExoticComponent<
    RN.TextInputProps & React.RefAttributes<RN.TextInput>
  >
}) => ...

But in this case, when trying to pass RN.TextInput as prop, I get:

<MyComp MyInput={RN.TextInput} />
/*
Property '$$typeof' is missing in type 'typeof TextInput' but required in type 'ForwardRefExoticComponent<TextInputProps & RefAttributes<TextInput>>'.ts(2741)
*/

Here is a sandbox showing the issue

Advertisement

Answer

Adding typeof TextInput solve the TS error for me

const MyComp = (props: {
  MyInput: React.ForwardRefExoticComponent<
    RN.TextInputProps & React.RefAttributes<RN.TextInput>
  > | typeof TextInput
}) => ...

I think you don’t even need the exotic type because TextInput itself already is capable of receiving a ref

const MyComp = (props: {
  MyInput: typeof TextInput
}) => ...
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement