The core libdef for Object.keys is clear as can be:
declare class Object {
// [snip]
static keys(o: any): Array<string>;
// [snip]
}
(
|
static keys(o: any): Array<string>; |
)
This suggests that the following code should have a type error:
// @flow
type K = "A" | "B";
const x: {[K]: number} = {};
(Object.keys(x): Array<K>); // `string` should be incompatible with `K`
And yet the above code typechecks. Why?
This was not always the case. The above code did not typecheck in Flow v0.59.0, but has typechecked since Flow v0.60.0. But the release notes for v0.60.0 don’t mention such a change.
Also, this does not work if the key type is opaque (possibly related to #6569 and friends):
// @flow
declare opaque type O: string;
const y: {[O]: number} = {};
(Object.keys(y): Array<O>); // fails (sad)
Having the refined type is quite useful, though the grievances in #5210 (from before the change) are legitimate. What is going on? Whence the inconsistency between the libdef, the working example with a transparent subtype of string, and the failing example with an opaque subtype of string?
(Full Flow-Try here.)
The core libdef for
Object.keysis clear as can be:(
flow/lib/core.js
Line 58 in 172d28f
This suggests that the following code should have a type error:
And yet the above code typechecks. Why?
This was not always the case. The above code did not typecheck in Flow v0.59.0, but has typechecked since Flow v0.60.0. But the release notes for v0.60.0 don’t mention such a change.
Also, this does not work if the key type is opaque (possibly related to #6569 and friends):
Having the refined type is quite useful, though the grievances in #5210 (from before the change) are legitimate. What is going on? Whence the inconsistency between the libdef, the working example with a transparent subtype of
string, and the failing example with an opaque subtype ofstring?(Full Flow-Try here.)