-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Description
The core libdef for Object.keys is clear as can be:
declare class Object {
// [snip]
static keys(o: any): Array<string>;
// [snip]
}(
Line 58 in 172d28f
| 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?