Skip to content
Permalink
Browse files

$Keys should produce a union of SingletonStrTs instead of StrTs

Summary: Previously $Keys would produce a StrT union, which would not trigger the union optimizations we had in place for enums.

Reviewed By: avikchaudhuri

Differential Revision: D15361159

fbshipit-source-id: da5068151b051c5738a55bc3ff42d9197263cc28
  • Loading branch information...
dsainati1 authored and facebook-github-bot committed May 24, 2019
1 parent 5c0e5f0 commit 49c3e5e86c2039d050bd03a015058bf35cab13ac
Showing with 28 additions and 5 deletions.
  1. +8 −5 src/typing/flow_js.ml
  2. +20 −0 tests/keys/enum.js
@@ -2722,7 +2722,7 @@ let rec __flow cx ((l: Type.t), (u: Type.use_t)) trace =
(* flow the union of keys of l to keys *)
let keylist = SMap.fold (fun x _ acc ->
let reason = replace_reason_const (RStringLit x) reason_op in
DefT (reason, bogus_trust (), StrT (Literal (None, x)))::acc
DefT (reason, bogus_trust (), SingletonStrT x)::acc
) (Context.find_props cx props_tmap) [] in
rec_flow cx trace (union_of_ts reason_op keylist, keys);
Option.iter dict_t (fun { key; _ } ->
@@ -2737,7 +2737,7 @@ let rec __flow cx ((l: Type.t), (u: Type.use_t)) trace =
let own_props = Context.find_props cx instance.own_props in
let keylist = SMap.fold (fun x _ acc ->
let reason = replace_reason_const (RStringLit x) reason_op in
DefT (reason, bogus_trust (), StrT (Literal (None, x)))::acc
DefT (reason, bogus_trust (), SingletonStrT x)::acc
) own_props [] in
rec_flow cx trace (union_of_ts reason_op keylist, keys)

@@ -9444,9 +9444,12 @@ and sentinel_prop_test_generic key cx trace result orig_obj =
if orig_obj = obj then rec_flow_t cx trace (orig_obj, result)
in
let sentinel_of_literal = function
| DefT (_, _, StrT (Literal (_, value))) -> Some Enum.(One (Str value))
| DefT (_, _, NumT (Literal (_, value))) -> Some Enum.(One (Num value))
| DefT (_, _, BoolT (Some value)) -> Some Enum.(One (Bool value))
| DefT (_, _, StrT (Literal (_, value)))
| DefT (_, _, SingletonStrT value) -> Some Enum.(One (Str value))
| DefT (_, _, NumT (Literal (_, value)))
| DefT (_, _, SingletonNumT value) -> Some Enum.(One (Num value))
| DefT (_, _, BoolT (Some value))
| DefT (_, _, SingletonBoolT value) -> Some Enum.(One (Bool value))
| DefT (_, _, VoidT) -> Some Enum.(One Void)
| DefT (_, _, NullT) -> Some Enum.(One Null)
| UnionT (_, rep) ->
@@ -0,0 +1,20 @@
// @flow

function foo(r: $Keys<typeof R>): boolean {
switch (r) {
case R.A:
return false;
case R.B:
return false;
default:
return true;
}
}

const R: {|
A: 'A',
B: 'B',
|} = {
A: 'A',
B: 'B',
};

0 comments on commit 49c3e5e

Please sign in to comment.
You can’t perform that action at this time.