How to get flow to typecheck props given to it from a HOC?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



How to get flow to typecheck props given to it from a HOC?



For example:


import withProps from 'recompose'

type Props =
name: string,
;

const NameTag = ( name : Props) => (
<p style=color: 'pink'>
name
</p>
);

const MyNameTag = withProps(
// i want a error here
name: 1
)(NameTag);



How can I get an error that I cannot pass the number 1 to the prop name for the NameTag component?


1


name



Thanks.




1 Answer
1



At least Flow 0.78 will give you an error as soon as you use the HOC.



So if you add a <MyNameTag /> on your code, it should give you this.


<MyNameTag />


string [1] is incompatible with number [2] in property name of the first argument.

[1] 7│ name: string,
8│ };
9│
10│ const NameTag = ( name : Props) => (
11│ <p style=color: 'pink'>
12│ name
13│ </p>
:
[2] 19│ name: 1



This probably happens because you can still pass name when instancing NameTag and up until that point it's not clear that it will fail.


name


NameTag



Flow is so complex and my flow-fu is weak so I would not dare to say this is a flow bug.



So far, the only way I have found to catch errors on declarations is to build a HOC that only allows the properties that were not overridden and nothing else. You will need to declare components with strict properties a: string . Check this example:


a: string


// @flow

import * as React from 'react'


function myWithProps<
MP, // My Properties. These are the pre-entered properties.
CP, // Component properties. The properties originally expected by
// the component.
C: React.ComponentType<CP>, // The original component itself. Used to
// extract the properties template CP.
IP: $Diff<CP, MP>, // Input properties. Properties that must be received
// by the HOC. We only expect the properties of the
// original component CP minus the properties MP that
// were specified when we created the HOC.
>(myProps: MP): C => React.ComponentType<IP>
return component => props => <component ...myProps ...props />;



type Props =
name: string,
age: number,
;


const NameTag = ( name, age : Props) => (
<p style=color: 'pink'>
name age
</p>
);


// $ExpectError. name has a wrong type.
const MyNameTag = myWithProps(name: 1)(NameTag);

// Should work.
const MyOtherNameTag = myWithProps(name: "hello")(NameTag);

// Should work.
<MyOtherNameTag age=21 />;

// $ExpectError. name cannot be overriden.
<MyOtherNameTag age=21 name="John" />;

// $ExpectError. age has a wrong type.
<MyOtherNameTag age="21" />;

// $ExpectError. age missing.
<MyOtherNameTag />;

// $ExpectError. Unexpected parameter.
<MyOtherNameTag age=21 nmae="John" />;



myWithProps uses generic types so it should work with any class.



I hope this helps!





Thanks for the detailed reply. I am using the library 'recompose' so I would like to avoid making my own HOC's as much as possible. I am also using Flow v0.75 so I will try updating.
– nate
Aug 18 at 8:14






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard