Refining mixed to a known object type in Flow

喜夏-厌秋 提交于 2021-02-07 20:52:49

问题


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.


回答1:


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; 
};


来源:https://stackoverflow.com/questions/45276951/refining-mixed-to-a-known-object-type-in-flow

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!