question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

HOC returned component props can not differ from HOC generic props

See original GitHub issue

TypeScript Version: 3.3.0-dev.20181208

Search Terms:

  • HOC
  • react
  • higher order component

Code

import * as React from 'react';

export interface HOCProps {
  foo: number;
}

/** Remove props, that have been prefilled by the HOC */
type WithoutPrefilled<T extends HOCProps> = Pick<T, Exclude<keyof T, 'foo'>>;

function withFoo<P extends HOCProps>(WrappedComponent: React.ComponentType<P>) {
  return class SomeHOC extends React.Component<WithoutPrefilled<P>> {
    public render(): JSX.Element {
      return <WrappedComponent {...this.props} foo={0} />;
    }
  };
}

Expected behavior: No error, like with every version below 3.2.0.

Actual behavior: Throws an error highlighting the WrappedComponent in the render method.

[ts]
Type 'Readonly<{ children?: ReactNode; }> & Readonly<Pick<P, Exclude<keyof P, "foo">>> & { foo: number; }' is not assignable to type 'IntrinsicAttributes & P & { children?: ReactNode; }'.
  Type 'Readonly<{ children?: ReactNode; }> & Readonly<Pick<P, Exclude<keyof P, "foo">>> & { foo: number; }' is not assignable to type 'P'. [2322]

Additional Information

This is pretty much the same sample example used in https://github.com/Microsoft/TypeScript/issues/28720, but with the difference, that the props of the returned component differ from the generic.

Basically the HOC prefills the foo property for the WrappedComponent. Since the spreaded props are overriden by foo, I don’t want foo to be a valid property for the HOC. This does not seem to be possible anymore.

Playground Link:

Related Issues: https://github.com/Microsoft/TypeScript/issues/28720

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:75
  • Comments:19 (3 by maintainers)

github_iconTop GitHub Comments

58reactions
ChristianIviceviccommented, Dec 31, 2018

Starting with 3.2 the behaviour of the spread operator for generics has changed. Apparently the type of props gets erased as a negative side effect, but you can work around that by casting it back to P using {...props as P} when spreading back into the wrapped component.

16reactions
weswighamcommented, Dec 10, 2018

@ahejlsberg The change is that we no longer erase generics in JSX (so we actually check these calls now), and roughly that Pick<P, Exclude<keyof P, "foo">> & { foo: P["foo"] } doesn’t recombine to (or get recognized as assignable to) P. It’s an unfortunate interaction with generic rest/spread, and the error we output is bad, too.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Typescript with React - use HOC on a generic component class
EDIT: The problem is that I want to be able to have something like <FooWithTd<number> {...someprops}/> later on, as I don't know the...
Read more >
Typing Higher Order Components in React using TypeScript
I have a generic component A, whose props is type Props = PubProps<B> & InjectedProps ... React Higher Order Components (HOC) in TypeScript....
Read more >
React Higher-Order Components in TypeScript - Medium
Here we are defining a component to return from the HOC, and specifying that the component will include the passed in component's props...
Read more >
Section 1: React HOC docs in TypeScript
Example HOC from React Docs translated to TypeScript ... data: T; // data is generic ... P is the props of the wrapped...
Read more >
React Higher-Order Components (HOCs) - Robin Wieruch
If the latter wouldn't be there, there would be a null pointer exception for the !props.data.length empty check. The withLoadingFeedback HOC is ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found