Hi, how should I annotate React Inheritance Inversion HoC function using generics? I want to inject new Foo props to WrappedComponent by Inheritance Inversion HoC without success...
/* @flow */
import React from 'react';
type Foo = {
foo: number;
}
type Bar = {
bar: number;
}
function hoc<P>(
WrappedComponent: Class<React$Component<void, P, void>>
): Class<React$Component<void, $Diff<P, Foo>, void>> {
return class Enhancer extends WrappedComponent {
props: $Diff<P, Foo>;
}
}
class A extends React.Component {
props: Bar;
}
const B = hoc(A);
const C = () => <B foo={1} bar={2}/>;
3 following errors occurred on this example.
12: function hoc<P>( ^ some incompatible instantiation of `P`. This type is incompatible with
12: function hoc<P>( ^ some incompatible instantiation of `P`
12: function hoc<P>(
^ P. Expected object instead of
12: function hoc<P>(
^ P
md5-3cf824a8e1bd48bf614f22c430040382
16: props: $Diff<P, Foo>;
^ P. This type is incompatible with
12: function hoc<P>( ^ some incompatible instantiation of `P`
https://flowtype.org/try/#0PQKgBAAgZgNg9gdzCYAoAlgWwA5wE4AuYASgKYCGAxkVHnJmAOR4XWMDcqqBAntqWABicOGAC8YAN6owYKCIBcYAHYBXTACNSeTgF8uvfmABC5POKkywGs0rWbt7MKn2ooq5dXRxlYABZwlAA8AAoAfAAUVgDqeOTY-AAmAML0uMqkygRKyTDkAM75QWRUBAAkqTg+mQRBAG5w6IkANGAhrQ1NYWGoAJQ5eYXFrOWV6TX1jS1gZQAi6FBQoa3CcGEdU92WsiwEqni+lIP5YACiyn7kntpgpAAeBJmJJ7HxSWPVWduyYNh02PklHMFkt2kIRGFOLJ9K4jgUTgBBW4PJ4nErUAB0HwyX2ksj+cABSlMOhcXEoPnyRGMFgClAiCN6nFQFOUVLAyQsEV64jCYCCNPkcDEkgAjLprGYRQAmXTASFcIA
Not exactly sure what you mean by "Inheritance Inversion," but based on the API indicated here...
js
const C = () => <B foo={1} bar={2}/>;
This is what I'd do:
````js
/* @flow */
import React from 'react';
type Foo = {
foo: number;
}
type Bar = {
bar: number;
}
function hoc
): Class
return class extends React.Component {
render() {
return
}
}
}
class A extends React.Component {
props: Bar;
}
const B = hoc(A);
const C = () => ;
````
https://flowtype.org/try/#0PQKgBAAgZgNg9gdzCYAoAlgWwA5wE4AuYASgKYCGAxkVHnJmAOR4XWMDcqqBAntqWABicOGAC8YAN6owYKCIBcYAHYBXTACNSeTgF8uvfmABC5POKkywGs0rWbt7MKn2ooq5dXRxlYABZwlAA8AApKkroAfAAUVgDC9LjKpMoESnEw5ADOWUFkVAQAJAk4PikEQQBucOgAJgA0YCGN1XWRkagAlOmZOXmsRSVJ5VU1DU1gAGQmZi1j7ZayLASqeL6UvVlgpAAeBCm1W-nUAHRDZamLsmAsyrXa0Z1X1zekK2tgQefJl5In-wQ-OgsidsHRsFldGBgB0XvpZPpXBtslsAILbPYHI4DM6JC5EaSyMFwCFKUw6FxcSg+LJEYwWAKUaKozqcVDU5S0sBxCyPcSRT70+RwMSSACMUJseFFACZdDDOEA
Eh, actually not what you are looking for... https://medium.com/@franleplant/react-higher-order-components-in-depth-cf9032ee6c3e#.5icjtqfuy
@mwalkerwells thanks!! Inheritance Inversion means extends WrappedComponent(not React.Component.). The above article is exactly that.
I want to check all props type (foo and bar in this example).
I fixed example with reference to your answer.
It works as expected but I do not know the right way....
/* @flow */
import React from 'react';
type Foo = {
foo: number;
}
type Bar = {
bar: number;
}
function hoc<P: any>(
WrappedComponent: Class<React$Component<void, P, void>>
): Class<React$Component<void, P & Foo, void>> {
return class Enhancer extends WrappedComponent {
props: P & Foo;
}
}
class A extends React.Component {
props: Bar;
}
const B = hoc(A);
const C = () => <B foo={1} bar={2}/>;
const C = () => <B foo={"1"} bar={2}/>; // Error
const C = () => <B foo={1} bar={"2"}/>; // Error
https://flowtype.org/try/#0PQKgBAAgZgNg9gdzCYAoAlgWwA5wE4AuYASgKYCGAxkVHnJmAOR4XWMDcqqBAntqWABicOGAC8YAN6owYKCIBcYAHYBXTACNSeTgF8uvfmABC5POKkywGs0rWbt7MKn2ooq5dXRxlYABZwlAA8AApK5Mo8AHwAFFYA6njk2PwAJgDC9LjKpMoESukw5ADOxUFkVAQAJJk4PrkEQQBucOipADRgIZ0tbVFRqACUBUWl5azVtdkNza0dXWAAZEIiPXP9lrIsBKp4vpSjxWAAosp+EZTaYKQAHgS5qUeJyWlT9XmbsmDYdNjFSiElis4JxZPpXAcSkcAILXO4PI4VagAOjeOQ+0lkPzgfyUph0Li4lB8xSIxgsAUoMWhg04qGJylJYHSFhig3EUTAQXJ8jgYkkAEZdNYzPyAEy6YBRThAA
I'd love to have someone else chime in here, but you can declare it separately from your code if needed...
````js
/* @flow */
import React from 'react';
type Foo = {
foo: number;
}
type Bar = {
bar: number;
}
declare function hoc<
Props: {},
Komponent: Class
(Component: Komponent): Class
>
class A extends React.Component {
props: Bar;
}
const B = hoc(A)
const C = () =>
````
This was my puzzle for the evening, thank you. 馃槂
My solution:
````js
/* @flow */
import React from 'react';
type Foo = {
foo: number;
}
type Bar = {
bar: number;
}
type __UnwrapType
type UnwrapType
type ReactComponentClass
function hoc<
T: Foo,
Component: ReactComponentClass<*>
(WrappedComponent: Component): ReactComponentClass
& T> {
return class Enhancer extends WrappedComponent {
props: T
}
}
class A extends React.Component {
props: Bar
}
const B = hoc(A);
const C = () =>
````
@mwalkerwells Thanks!!!
Curious if this works for your use case...
Close?
This works.
/* @flow */
import React from 'react';
type Foo = {
+foo: number;
}
type Bar = {
+bar: number;
}
function hoc<D, P, C: React$Component<D, P, void>>(
component: Class<C>
): Class<React$Component<D, P & Foo, void>> {
return class Enhancer extends WrappedComponent {
props: P & Foo;
}
}
class A extends React.Component {
props: Bar;
}
const B = hoc(A);
const C = () => <B foo={1} bar={2}/>;
@nmn Awsome!! 馃憤
@nmn What is your definition for WrappedComponent?
js
18: return class Enhancer extends WrappedComponent {
^ identifier `WrappedComponent`. Could not resolve name
@mwalkerwells WrappedComponent just comes from the original example given here. Disregard it.
Most helpful comment
This was my puzzle for the evening, thank you. 馃槂
My solution:
````js
/* @flow */
import React from 'react';
type Foo = {
foo: number;
}
type Bar = {
bar: number;
}
type __UnwrapType> = T = __UnwrapType<*, T>
type UnwrapType
type ReactComponentClass>
function hoc<
T: Foo,
Component: ReactComponentClass<*>
class A extends React.Component {
props: Bar
}
const B = hoc(A);
const C = () =>
````