Búsqueda de sitios web

reactjs - Usando React forwardRef con argumentos JSX genéricos en Typescript


Dado el siguiente componente de React tipado que usa argumentos de tipo genérico, ¿cómo podría envolverlo en la nueva API forwardRef de React?

type Props<T> = {
  forwardedRef?: Ref<HTMLInputElement>
  ...
}

class GenericComponent<T> extends Component<Props<T>> {
  ...
}

const ComponentWithRef = forwardRef<HTMLInputElement, Props<T>>((props, ref) => (
  <StringInput<T> {...props} forwardedRef={ref} />
))

El enfoque anterior no tiene forma de definir el genérico T.

Respuesta #1

Entonces, para ampliar un poco la pregunta, esto es realmente una pregunta sobre cómo preservar los tipos genéricos en funciones de orden superior. El siguiente uso de forwardRef se verificará correctamente (en 3.0.1)

const SelectWithRef = forwardRef(<Option extends string>(props: Props<Option>, ref?: Ref<HTMLSelectElement>) =>
  <Select<Option> {...props} forwardedRef={ref} />);

Pero, el genérico Option se resuelve inmediatamente a string, en lugar de permanecer como un genérico. Por lo tanto, lo siguiente no verifica el tipo

const onChange: (value: 'one' | 'two') => void = (value) => console.log(value);

<SelectWithRef<'one' | 'two'>
              ^^^^^^^^^^^^^^^ [ts] Expected 0 type arguments, but got 1
  value="a"
  options={['one', 'two']}
  onChange={onChange}
           ^^^^^^^^^^ [ts] Type 'string' is not assignable to type '"one" | "two"'
/>

El asunto relevante se rastrea en este ticket de incidencia de Typescript.

Artículos relacionados