Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React HOC and TypeScript 3.2

As TypeScript improve its JSX type-checking in v3.2, we have a problem to correctly type our HOCs now.

Can someone fix types in the following HOC for TypeScript 3.2?

import { ComponentType } from 'react';  type Props = { custom: string }; type Omit<T, K extends string> = Pick<T, Exclude<keyof T, K>>;  function hoc<P extends Props>(Component: ComponentType<P>) {   return (props: Omit<P, keyof Props>) => {     return <Component {...props} custom="text" />;   } } 

TypeScript error:

Type '{ custom: string; }' is not assignable to type 'IntrinsicAttributes & P & { children?: ReactNode; }'. Property 'custom' does not exist on type 'IntrinsicAttributes & P & { children?: ReactNode; }' 

Basically, the idea is to transform the component which requires "custom" property to component, which doesn't need it anymore as it will be injected automatically by HOC.

EDIT: Probably the same issue: https://github.com/Microsoft/TypeScript/issues/28748

like image 229
Deftomat Avatar asked Nov 30 '18 10:11

Deftomat


People also ask

Is hoc still used in react?

HOCs are not part of the React API, per se. They are a pattern that emerges from React's compositional nature. Concretely, a higher-order component is a function that takes a component and returns a new component.

Can we use Hoc with hooks?

HOC is a function that takes a component as an argument and returns an enhanced version. HOC helps to isolate logic and state management in a separate class-based component. With React Hooks, state management can occur outside of a class. Hooks empower developers to use the functional programming aspects in React.


1 Answers

I'm sure this is not the answer that you were hoping for, but you can make it work by changing the type of props in the inner function to any, and putting the Omit type in the return type annotation of the outer function, like this:

function hoc<P extends Props>(Component: ComponentType<P>): ComponentType<Omit<P, keyof Props>> {   return (props: any) => {     return <Component {...props} custom="text" />;   } } 
like image 145
Jesse Hallett Avatar answered Sep 29 '22 08:09

Jesse Hallett