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