问题
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