Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Refining mixed to a known object type in Flow

We're trying to do type refinement in Flow to guard against values entering our application at the external interfaces. To do this we're using mixed and then trying to refine to known types, but Flow isn't make it easy!

The following seems like it should work, I've validated that the mixed type value matches the requirements of the response type.

type Response = { head: string }

const refineToResponse = (value: mixed): ?Response => {   
  if (value
    && typeof value === "object"
    && typeof value.head === "string") {

    return value;   
  }

  return null; 
};

But I just get a very unhelpful error message:

16:     return value;
               ^^^^^ object. This type is incompatible with the expected return type of
11: const refineToResponse = (value: mixed): ?Response => {
                                              ^^^^^^^^ object type   

Property head is incompatible:

 11: const refineToResponse = (value: mixed): ?Response => {
                                                 ^^^^^ mixed. This type is incompatible with
  8:   head: string
             ^^^^^^ string

Edit:

A link to the code on TryFlow.

like image 436
Dan Avatar asked Jan 22 '26 02:01

Dan


1 Answers

That would be unsafe. If something has type string at runtime, it doesn't mean that it has the same static type, e.g. it could be some enum: 'Foo' | 'Bar', so making it just string would allow unsafe mutations. On the other hand, it could be number | string, so in the future head could become a number or any type, really.

Instead you can do the following:

const refineToResponse = (value: mixed): ?Response => {   
  if (value
    && typeof value === "object"
    && typeof value.head === "string") {

    return { head: value.head };   
  }

  return null; 
};
like image 198
vkurchatkin Avatar answered Jan 23 '26 14:01

vkurchatkin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!