Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic support for typeof x === 'symbol' #7405

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/common/reason.ml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ end

type reason_desc =
| RAnyExplicit | RAnyImplicit
| RNumber | RString | RBoolean | RMixed | REmpty | RVoid | RNull
| RNumber | RString | RBoolean | RMixed | REmpty | RVoid | RNull | RSymbol
| RNullOrVoid
| RLongStringLit of int (* Max length *)
| RStringLit of string
Expand Down Expand Up @@ -398,6 +398,7 @@ let rec string_of_desc = function
| RVoid -> "undefined"
| RNull -> "null"
| RNullOrVoid -> "null or undefined"
| RSymbol -> "symbol"
| RStringLit "" -> "empty string"
| RStringLit x -> spf "string literal `%s`" x
| RNumberLit x -> spf "number literal `%s`" x
Expand Down Expand Up @@ -1071,6 +1072,7 @@ let inferred_union_elem_array_desc = RCustom
let classification_of_reason r = match desc_of_reason ~unwrap:true r with
| RNumber
| RString
| RSymbol
| RBoolean
| RLongStringLit _
| RStringLit _
Expand Down
2 changes: 1 addition & 1 deletion src/common/reason.mli
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ val mk_id: unit -> int

type reason_desc =
| RAnyExplicit | RAnyImplicit
| RNumber | RString | RBoolean | RMixed | REmpty | RVoid | RNull
| RNumber | RString | RBoolean | RMixed | REmpty | RVoid | RNull | RSymbol
| RNullOrVoid
| RLongStringLit of int (* Max length *)
| RStringLit of string
Expand Down
3 changes: 3 additions & 0 deletions src/typing/debug_js.ml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ let string_of_pred_ctor = function
| FunP -> "FunP"
| ObjP -> "ObjP"
| ArrP -> "ArrP"
| SymbolP -> "SymbolP"
| SingletonBoolP _ -> "SingletonBoolP"
| SingletonStrP _ -> "SingletonStrP"
| SingletonNumP _ -> "SingletonNumP"
Expand Down Expand Up @@ -1335,6 +1336,7 @@ and json_of_pred_impl json_cx p = Hh_json.(
| MaybeP
| BoolP
| StrP
| SymbolP
| NumP
| FunP
| ObjP
Expand Down Expand Up @@ -1677,6 +1679,7 @@ let rec dump_t_ (depth, tvars) cx t =
| Mixed_non_maybe -> "Mixed_non_maybe"
| Mixed_non_null -> "Mixed_non_null"
| Mixed_non_void -> "Mixed_non_void"
| Mixed_symbol -> "Mixed_symbol"
| Empty_intersection -> "Empty_intersection"
in

Expand Down
10 changes: 10 additions & 0 deletions src/typing/flow_js.ml
Original file line number Diff line number Diff line change
Expand Up @@ -8727,6 +8727,16 @@ and predicate cx trace t l p = match p with
| NotP StrP ->
rec_flow_t cx trace (Type_filter.not_string l, t)

(***********************)
(* typeof _ ~ "symbol" *)
(***********************)

| SymbolP ->
rec_flow_t cx trace (Type_filter.symbol l, t)

| NotP SymbolP ->
rec_flow_t cx trace (Type_filter.not_symbol l, t)

(*********************)
(* _ ~ "some string" *)
(*********************)
Expand Down
1 change: 1 addition & 0 deletions src/typing/statement.ml
Original file line number Diff line number Diff line change
Expand Up @@ -5465,6 +5465,7 @@ and predicates_of_condition cx e = Ast.(Expression.(
| "number" -> Some NumP
| "object" -> Some ObjP
| "string" -> Some StrP
| "symbol" -> Some SymbolP
| "undefined" -> Some VoidP
| _ -> None
in
Expand Down
3 changes: 3 additions & 0 deletions src/typing/type.ml
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,7 @@ module rec TypeTerm : sig
| NumP (* number *)
| ObjP (* object *)
| StrP (* string *)
| SymbolP (* symbol *)
| VoidP (* undefined *)

| ArrP (* Array.isArray *)
Expand Down Expand Up @@ -753,6 +754,7 @@ module rec TypeTerm : sig
| Mixed_non_null
| Mixed_non_void
| Mixed_function
| Mixed_symbol
| Empty_intersection

and any_source =
Expand Down Expand Up @@ -3194,6 +3196,7 @@ let rec string_of_predicate = function
| NumP -> "number"
| FunP -> "function"
| ObjP -> "object"
| SymbolP -> "symbol"

(* Array.isArray *)
| ArrP -> "array"
Expand Down
14 changes: 14 additions & 0 deletions src/typing/type_filter.ml
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,19 @@ let not_string t =
| DefT (_, (AnyT _ | StrT _)) -> DefT (reason_of_t t, EmptyT)
| _ -> t

let symbol t =
match t with
| DefT (r, MixedT _) ->
DefT (replace_reason_const RSymbol r, MixedT Mixed_symbol)
| _ ->
(* TODO: since symbols aren't supported, `t` is never a symbol so always empty *)
let reason = reason_of_t t in
DefT (replace_reason_const RSymbol reason, EmptyT)

let not_symbol t =
(* TODO: since symbols aren't supported, `t` is never a symbol so always pass it through *)
t

let number t =
match t with
| DefT (r, MixedT Mixed_truthy) -> DefT (replace_reason_const NumT.desc r, NumT Truthy)
Expand All @@ -307,6 +320,7 @@ let object_ cx t =
let proto = ObjProtoT reason in
let obj = Obj_type.mk_with_proto cx reason ?dict proto in
begin match flavor with
| Mixed_symbol
| Mixed_truthy
| Mixed_non_maybe
| Mixed_non_null -> obj
Expand Down
1 change: 1 addition & 0 deletions src/typing/type_mapper.ml
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,7 @@ class virtual ['a] t = object(self)
| NumP
| ObjP
| StrP
| SymbolP
| VoidP
| ArrP
| PropExistsP _ -> p
Expand Down
1 change: 1 addition & 0 deletions src/typing/type_visitor.ml
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ class ['a] t = object(self)
| NumP -> acc
| ObjP -> acc
| StrP -> acc
| SymbolP -> acc
| VoidP -> acc
| ArrP -> acc
| PropExistsP _ -> acc
Expand Down
19 changes: 18 additions & 1 deletion tests/refinements/refinements.exp
Original file line number Diff line number Diff line change
Expand Up @@ -3081,6 +3081,23 @@ References:
^^^^^ [2]


Error --------------------------------------------------------------------------------------------------- typeof.js:83:6

Cannot cast `x` to string because symbol [1] is incompatible with string [2].

typeof.js:83:6
83| (x: string); // error
^

References:
typeof.js:81:24
81| function testSymbol(x: mixed) {
^^^^^ [1]
typeof.js:83:9
83| (x: string); // error
^^^^^^ [2]


Error --------------------------------------------------------------------------------------------------- undef.js:31:13

Cannot perform arithmetic operation because null or undefined [1] is not a number.
Expand Down Expand Up @@ -3350,4 +3367,4 @@ Cannot perform arithmetic operation because undefined [1] is not a number.



Found 242 errors
Found 243 errors
6 changes: 6 additions & 0 deletions tests/refinements/typeof.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,9 @@ function testInstanceIsObject() {
(x: empty); // error
}
}

function testSymbol(x: mixed) {
if (typeof x === "symbol") { // ok
(x: string); // error
}
}