From 2df7671e7bda770b95e6b1eaede96d7a8ab1f2ac Mon Sep 17 00:00:00 2001 From: Avik Chaudhuri Date: Fri, 10 Jun 2016 00:30:07 -0700 Subject: [PATCH] fate of the union (a.k.a. the roads not taken) Summary: This diff re-implements how union (and intersection) types are checked in Flow, fixing serious bugs in the current system. The problem =========== Flow's inference engine is designed to find more errors over time as constraints are added...but it is not designed to backtrack. Unfortunately, checking the type of an expression against a union type does need backtracking: if some branch of the union doesn't work out, the next branch must be tried, and so on. The situation is further complicated by the fact that the type of the expression may be unknown at the point of checking, so that a branch that looks promising now might turn out to be incorrect later. The solution ============ The basic idea is to delay trying a branch until a point where we can decide whether the branch will definitely fail or succeed, without adding constraints. If trying the branch results in failure, we can move on to the next branch without needing to backtrack. If the branch succeeds, we are done. The final case is where the branch looks promising, but we cannot be sure without adding constraints: in this case we try other branches, and *bail* when we run into ambiguities...requesting additional annotations to decide which branch to select. Overall, this means that (1) we never commit to a branch that might turn out to be incorrect and (2) can always select a correct branch (if such exists) given enough annotations. As a matter of implementation, we need to distinguish between annotations and inferred types for this scheme to work: in particular, we fully resolve annotations before branches are tried, and then use whatever partial information we can obtain from inferred types to disambiguate those branches. Fixes https://github.com/facebook/flow/issues/1759 Fixes https://github.com/facebook/flow/issues/1664 Fixes https://github.com/facebook/flow/issues/1663 Fixes https://github.com/facebook/flow/issues/1462 Fixes https://github.com/facebook/flow/issues/1455 Fixes https://github.com/facebook/flow/issues/1371 Fixes https://github.com/facebook/flow/issues/1349 Fixes https://github.com/facebook/flow/issues/824 Fixes https://github.com/facebook/flow/issues/815 Reviewed By: bhosmer Differential Revision: D3229344 fbshipit-source-id: 64da005f4a7eaa4b6a8c74c535b27ab24c7b80bc --- lib/core.js | 37 +- src/common/reason_js.ml | 54 +- src/common/reason_js.mli | 10 +- src/services/inference/infer_service.ml | 5 +- src/services/inference/merge_service.ml | 2 +- src/services/inference/types_js.ml | 1 - src/typing/class_sig.ml | 2 +- src/typing/context.ml | 16 + src/typing/context.mli | 4 + src/typing/debug_js.ml | 45 +- src/typing/flow_error.ml | 36 +- src/typing/flow_js.ml | 1417 +++++++++++++++------ src/typing/funType.ml | 154 --- src/typing/graph_explorer.ml | 198 +++ src/typing/merge_js.ml | 4 + src/typing/partition.ml | 59 - src/typing/speculation.ml | 177 +++ src/typing/statement.ml | 71 +- src/typing/type.ml | 79 +- src/typing/type_annotation.ml | 26 +- src/typing/type_normalizer.ml | 4 +- src/typing/type_printer.ml | 9 +- src/typing/type_visitor.ml | 11 +- tests/arraylib/arraylib.exp | 101 +- tests/arrows/arrows.exp | 2 +- tests/async/async.exp | 34 +- tests/autocomplete/autocomplete.exp | 4 +- tests/call_properties/call_properties.exp | 20 +- tests/core_tests/core_tests.exp | 142 +-- tests/core_tests/map.js | 2 +- tests/date/date.exp | 22 +- tests/dom/dom.exp | 883 +++++-------- tests/dump-types/dump-types.exp | 4 +- tests/generators/class.js | 8 +- tests/generators/class_failure.js | 5 +- tests/generators/generators.exp | 58 +- tests/intersection/objassign.js | 2 +- tests/intersection/test_fun.js | 2 +- tests/intersection/test_obj.js | 2 +- tests/iterable/iterable.exp | 39 +- tests/misc/misc.exp | 2 +- tests/node_tests/node_tests.exp | 134 +- tests/object_api/object_api.exp | 2 +- tests/objects/objects.exp | 76 +- tests/overload/overload.exp | 10 +- tests/promises/promises.exp | 348 ++--- tests/refinements/tagged_union.js | 2 +- tests/union/union.exp | 25 +- tests/union_new/.flowconfig | 2 + tests/union_new/issue-1349.js | 6 + tests/union_new/issue-1371.js | 7 + tests/union_new/issue-1455-helper.js | 3 + tests/union_new/issue-1455.js | 9 + tests/union_new/issue-1462-i.js | 22 + tests/union_new/issue-1462-ii.js | 27 + tests/union_new/issue-1664.js | 26 + tests/union_new/issue-1759.js | 8 + tests/union_new/issue-815.js | 21 + tests/union_new/issue-824-helper.js | 12 + tests/union_new/issue-824.js | 16 + tests/union_new/lib/test23_lib.js | 1 + tests/union_new/lib/test25_lib.js | 21 + tests/union_new/lib/test32_lib.js | 1 + tests/union_new/test1.js | 60 + tests/union_new/test10.js | 72 ++ tests/union_new/test11.js | 18 + tests/union_new/test12.js | 9 + tests/union_new/test13.js | 11 + tests/union_new/test14.js | 13 + tests/union_new/test15.js | 18 + tests/union_new/test16.js | 18 + tests/union_new/test17.js | 7 + tests/union_new/test18.js | 12 + tests/union_new/test19.js | 12 + tests/union_new/test2.js | 77 ++ tests/union_new/test20.js | 14 + tests/union_new/test21.js | 21 + tests/union_new/test22.js | 21 + tests/union_new/test23.js | 12 + tests/union_new/test24.js | 30 + tests/union_new/test25.js | 13 + tests/union_new/test26.js | 20 + tests/union_new/test27.js | 20 + tests/union_new/test28-helper.js | 69 + tests/union_new/test28.js | 19 + tests/union_new/test29.js | 31 + tests/union_new/test3.js | 29 + tests/union_new/test30-helper.js | 6 + tests/union_new/test30.js | 9 + tests/union_new/test31.js | 25 + tests/union_new/test32.js | 9 + tests/union_new/test4.js | 36 + tests/union_new/test5.js | 27 + tests/union_new/test6.js | 25 + tests/union_new/test7.js | 29 + tests/union_new/test8.js | 23 + tests/union_new/test9.js | 16 + tests/union_new/union_new.exp | 332 +++++ 98 files changed, 3713 insertions(+), 1982 deletions(-) delete mode 100644 src/typing/funType.ml create mode 100644 src/typing/graph_explorer.ml delete mode 100644 src/typing/partition.ml create mode 100644 src/typing/speculation.ml create mode 100644 tests/union_new/.flowconfig create mode 100644 tests/union_new/issue-1349.js create mode 100644 tests/union_new/issue-1371.js create mode 100644 tests/union_new/issue-1455-helper.js create mode 100644 tests/union_new/issue-1455.js create mode 100644 tests/union_new/issue-1462-i.js create mode 100644 tests/union_new/issue-1462-ii.js create mode 100644 tests/union_new/issue-1664.js create mode 100644 tests/union_new/issue-1759.js create mode 100644 tests/union_new/issue-815.js create mode 100644 tests/union_new/issue-824-helper.js create mode 100644 tests/union_new/issue-824.js create mode 100644 tests/union_new/lib/test23_lib.js create mode 100644 tests/union_new/lib/test25_lib.js create mode 100644 tests/union_new/lib/test32_lib.js create mode 100644 tests/union_new/test1.js create mode 100644 tests/union_new/test10.js create mode 100644 tests/union_new/test11.js create mode 100644 tests/union_new/test12.js create mode 100644 tests/union_new/test13.js create mode 100644 tests/union_new/test14.js create mode 100644 tests/union_new/test15.js create mode 100644 tests/union_new/test16.js create mode 100644 tests/union_new/test17.js create mode 100644 tests/union_new/test18.js create mode 100644 tests/union_new/test19.js create mode 100644 tests/union_new/test2.js create mode 100644 tests/union_new/test20.js create mode 100644 tests/union_new/test21.js create mode 100644 tests/union_new/test22.js create mode 100644 tests/union_new/test23.js create mode 100644 tests/union_new/test24.js create mode 100644 tests/union_new/test25.js create mode 100644 tests/union_new/test26.js create mode 100644 tests/union_new/test27.js create mode 100644 tests/union_new/test28-helper.js create mode 100644 tests/union_new/test28.js create mode 100644 tests/union_new/test29.js create mode 100644 tests/union_new/test3.js create mode 100644 tests/union_new/test30-helper.js create mode 100644 tests/union_new/test30.js create mode 100644 tests/union_new/test31.js create mode 100644 tests/union_new/test32.js create mode 100644 tests/union_new/test4.js create mode 100644 tests/union_new/test5.js create mode 100644 tests/union_new/test6.js create mode 100644 tests/union_new/test7.js create mode 100644 tests/union_new/test8.js create mode 100644 tests/union_new/test9.js create mode 100644 tests/union_new/union_new.exp diff --git a/lib/core.js b/lib/core.js index 1c82a8492ae..77bd0c176fc 100644 --- a/lib/core.js +++ b/lib/core.js @@ -196,20 +196,22 @@ declare class Array { map(callbackfn: (value: T, index: number, array: Array) => U, thisArg?: any): Array; pop(): T; push(...items: Array): number; + reduce( + callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: Array) => T, + initialValue: void + ): T; reduce( callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: Array) => U, initialValue: U ): U; - reduce( - callbackfn: (previousValue: T|U, currentValue: T, currentIndex: number, array: Array) => U - ): U; + reduceRight( + callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: Array) => T, + initialValue: void + ): T; reduceRight( callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: Array) => U, initialValue: U ): U; - reduceRight( - callbackfn: (previousValue: T|U, currentValue: T, currentIndex: number, array: Array) => U - ): U; reverse(): Array; shift(): T; slice(start?: number, end?: number): Array; @@ -421,10 +423,7 @@ interface Generator<+Yield,+Return,-Next> { declare class Map { @@iterator(): Iterator<[K, V]>; - constructor(_: void): Map; - constructor(_: null): Map; - constructor(iterable: Array<[Key, Value]>): Map; - constructor(iterable: Iterable<[Key, Value]>): Map; + constructor(iterable: ?Iterable<[K, V]>): void; clear(): void; delete(key: K): boolean; entries(): Iterator<[K, V]>; @@ -462,9 +461,7 @@ declare class Set { } declare class WeakSet { - constructor(_: void): WeakSet; - constructor(iterable: Array): WeakSet; - constructor(iterable: Iterable): WeakSet; + constructor(iterable?: Iterable): void; add(value: T): WeakSet; delete(value: T): boolean; has(value: T): boolean; @@ -549,22 +546,22 @@ declare class $TypedArray { keys(): Array; lastIndexOf(searchElement: number, fromIndex?: number): number; // -1 if not present map(callback: (currentValue: number, index: number, array: this) => number, thisArg?: any): this; + reduce( + callback: (previousValue: number, currentValue: number, index: number, array: this) => number, + initialValue: void + ): number; reduce( callback: (previousValue: U, currentValue: number, index: number, array: this) => U, initialValue: U ): U; - reduce( - callback: (previousValue: number|U, currentValue: number, index: number, array: this) => U, + reduceRight( + callback: (previousValue: number, currentValue: number, index: number, array: this) => number, initialValue: void - ): U; + ): number; reduceRight( callback: (previousValue: U, currentValue: number, index: number, array: this) => U, initialValue: U ): U; - reduceRight( - callback: (previousValue: number|U, currentValue: number, index: number, array: this) => U, - initialValue: void - ): U; reverse(): this; set(array: Array | $TypedArray, offset?: number): void; slice(begin?: number, end?: number): this; diff --git a/src/common/reason_js.ml b/src/common/reason_js.ml index b1666cfbe90..9d27d307d1d 100644 --- a/src/common/reason_js.ml +++ b/src/common/reason_js.ml @@ -216,6 +216,54 @@ let is_internal_module_name name = let internal_pattern_name loc = spf ".$pattern__%s" (string_of_loc loc) +let typeparam_prefix s = + spf "type parameter%s" s + +let has_typeparam_prefix s = + Utils.str_starts_with s "type parameter" + +let thistype_desc = "`this` type" +let existential_desc = "existential" + +(* Instantiable reasons identify tvars that are created for the purpose of + instantiation: they are fresh rather than shared, and should become types + that flow to them. We assume these characteristics when performing + speculative matching (even though we don't yet enforce them). *) +let is_instantiable_reason r = + let desc = desc_of_reason r in + has_typeparam_prefix desc + || desc = thistype_desc + || desc = existential_desc + +(* TODO: Property accesses create unresolved tvars to hold results, even when + the object(s) on which the property accesses happen may be resolved. This can + and should be fixed, for various benefits including but not limited to more + precise type inference. But meanwhile we need to consider results of property + accesses that might result in sentinel property values as constants to decide + membership in disjoint unions, instead of asking for unnecessary annotations + to make progress. According to Facebook's style guide, constant properties + should have names like CONSTANT_PROPERTY, so we bet that when properties with + such names are accessed, their types have the 0->1 property. + + As an example, suppose that we have an object `Tags` that stores tags of a + disjoint union, e.g. { ACTION_FOO: 'foo', ACTION_BAR: 'bar' }. + + Then the types of Tags.ACTION_FOO and Tags.ACTION_BAR are assumed to be 0->1. +*) +let is_constant_property_reason r = + let desc = desc_of_reason r in + let property_prefix = "property `" in + Utils.str_starts_with desc property_prefix && + let i = String.length property_prefix in + let j = String.index_from desc (i+1) '`' in + let property_name = String.sub desc i (j-i) in + try + String.iter (fun c -> + assert (c = '_' || Char.uppercase c = c) + ) property_name; + true + with _ -> false + let is_derivable_reason r = r.derivable @@ -243,10 +291,6 @@ let is_blamable_reason r = let reasons_overlap r1 r2 = Loc.(contains r1.loc r2.loc) -(* reasons compare on their locations *) -let compare r1 r2 = - Pervasives.compare (loc_of_reason r1) (loc_of_reason r2) - (* reason transformers: *) (* returns reason whose description is prefix-extension of original *) @@ -270,7 +314,7 @@ let replace_reason replacement reason = (* returns reason with new location and description of original *) let repos_reason loc reason = - mk_reason (desc_of_reason reason) loc + mk_reason_with_test_id reason.test_id (desc_of_reason reason) loc (* helper: strip root from positions *) let strip_root_from_loc root loc = Loc.( diff --git a/src/common/reason_js.mli b/src/common/reason_js.mli index 1f825f997ac..80c50502f17 100644 --- a/src/common/reason_js.mli +++ b/src/common/reason_js.mli @@ -39,6 +39,14 @@ val internal_module_name: string -> string val internal_pattern_name: Loc.t -> string +val typeparam_prefix: string -> string +val has_typeparam_prefix: string -> bool +val thistype_desc: string +val existential_desc: string +val is_instantiable_reason: reason -> bool + +val is_constant_property_reason: reason -> bool + val derivable_reason: reason -> reason val is_derivable_reason: reason -> bool @@ -71,8 +79,6 @@ val replace_reason: string -> reason -> reason val repos_reason: Loc.t -> reason -> reason -val compare: reason -> reason -> int - val do_patch: string list -> (int * int * string) list -> string val strip_root: Path.t -> reason -> reason diff --git a/src/services/inference/infer_service.ml b/src/services/inference/infer_service.ml index 61fce44b2f0..6d8409e20ec 100644 --- a/src/services/inference/infer_service.ml +++ b/src/services/inference/infer_service.ml @@ -48,10 +48,11 @@ let infer_module ~options ~metadata filename = let infer_job ~options (inferred, errsets, errsuppressions) files = let metadata = Context.metadata_of_options options in List.fold_left (fun (inferred, errsets, errsuppressions) file -> + let file_str = string_of_filename file in try Profile_utils.checktime ~options 1.0 - (fun t -> spf "perf: inferred %s in %f" (string_of_filename file) t) + (fun t -> spf "perf: inferred %s in %f" file_str t) (fun () -> - (*prerr_endlinef "[%d] INFER: %s" (Unix.getpid()) file;*) + (* prerr_endlinef "[%d] INFER: %s" (Unix.getpid()) file_str; *) (* infer produces a context for this module *) let cx = infer_module ~options ~metadata file in diff --git a/src/services/inference/merge_service.ml b/src/services/inference/merge_service.ml index f3f6f2b3197..8e0187a5024 100644 --- a/src/services/inference/merge_service.ml +++ b/src/services/inference/merge_service.ml @@ -170,7 +170,7 @@ let merge_strict_job ~options (merged, errsets) (components: filename list list) try Profile_utils.checktime ~options 1.0 (fun t -> spf "[%d] perf: merged %s in %f" (Unix.getpid()) files t) (fun () -> - (*prerr_endlinef "[%d] MERGE: %s" (Unix.getpid()) file;*) + (* prerr_endlinef "[%d] MERGE: %s" (Unix.getpid()) files; *) let file, errors = merge_strict_component ~options component in file :: merged, errors :: errsets ) diff --git a/src/services/inference/types_js.ml b/src/services/inference/types_js.ml index 5a433bf4dbf..dc213b15a66 100644 --- a/src/services/inference/types_js.ml +++ b/src/services/inference/types_js.ml @@ -210,7 +210,6 @@ let typecheck_contents ~options ?verbose contents filename = (* should never happen *) timing, None, errors, info - (* commit newly inferred and removed modules, collect errors. *) let commit_modules workers ~options inferred removed = let errmap = Module_js.commit_modules workers ~options inferred removed in diff --git a/src/typing/class_sig.ml b/src/typing/class_sig.ml index b07d651543e..7c62a887328 100644 --- a/src/typing/class_sig.ml +++ b/src/typing/class_sig.ml @@ -264,7 +264,7 @@ let add_this self cx reason tparams tparams_map = in let this_tp = { Type. name = "this"; - reason = replace_reason "`this` type" reason; + reason = replace_reason thistype_desc reason; bound = rec_instance_type; polarity = Type.Positive; default = None; diff --git a/src/typing/context.ml b/src/typing/context.ml index 4f66549e196..fc97ec6012c 100644 --- a/src/typing/context.ml +++ b/src/typing/context.ml @@ -51,6 +51,12 @@ type t = { (* map from evaluation ids to types *) mutable evaluated: Type.t IMap.t; + (* graph tracking full resolution of types *) + mutable type_graph: Graph_explorer.graph; + + (* map of speculation ids to sets of unresolved tvars *) + mutable all_unresolved: Type.TypeSet.t IMap.t; + (* map from frame ids to env snapshots *) mutable envs: env IMap.t; @@ -114,6 +120,8 @@ let make metadata file module_name = { envs = IMap.empty; property_maps = IMap.empty; evaluated = IMap.empty; + type_graph = Graph_explorer.new_graph ISet.empty; + all_unresolved = IMap.empty; modulemap = SMap.empty; errors = Errors_js.ErrorSet.empty; @@ -128,6 +136,7 @@ let make metadata file module_name = { } (* accessors *) +let all_unresolved cx = cx.all_unresolved let annot_table cx = cx.annot_table let envs cx = cx.envs let enable_const_params cx = cx.metadata.enable_const_params @@ -167,6 +176,7 @@ let should_munge_underscores cx = cx.metadata.munge_underscores let should_strip_root cx = cx.metadata.strip_root let suppress_comments cx = cx.metadata.suppress_comments let suppress_types cx = cx.metadata.suppress_types +let type_graph cx = cx.type_graph let type_table cx = cx.type_table let verbose cx = cx.metadata.verbose @@ -200,6 +210,8 @@ let remove_all_error_suppressions cx = cx.error_suppressions <- Errors_js.ErrorSuppressions.empty let remove_tvar cx id = cx.graph <- IMap.remove id cx.graph +let set_all_unresolved cx all_unresolved = + cx.all_unresolved <- all_unresolved let set_envs cx envs = cx.envs <- envs let set_evaluated cx evaluated = @@ -214,6 +226,8 @@ let set_module_exports_type cx module_exports_type = cx.module_exports_type <- module_exports_type let set_property_maps cx property_maps = cx.property_maps <- property_maps +let set_type_graph cx type_graph = + cx.type_graph <- type_graph let set_tvar cx id node = cx.graph <- IMap.add id node cx.graph @@ -235,5 +249,7 @@ let merge_into cx cx_other = set_envs cx (IMap.union (envs cx_other) (envs cx)); set_property_maps cx (IMap.union (property_maps cx_other) (property_maps cx)); set_evaluated cx (IMap.union (evaluated cx_other) (evaluated cx)); + set_type_graph cx (Graph_explorer.union_finished (type_graph cx_other) (type_graph cx)); + set_all_unresolved cx (IMap.union (all_unresolved cx_other) (all_unresolved cx)); set_globals cx (SSet.union (globals cx_other) (globals cx)); set_graph cx (IMap.union (graph cx_other) (graph cx)) diff --git a/src/typing/context.mli b/src/typing/context.mli index a1658ef6a68..3aa735613f6 100644 --- a/src/typing/context.mli +++ b/src/typing/context.mli @@ -39,6 +39,7 @@ val make: metadata -> Loc.filename -> Modulename.t -> t val metadata_of_options: Options.t -> metadata (* accessors *) +val all_unresolved: t -> Type.TypeSet.t IMap.t val annot_table: t -> (Loc.t, Type.t) Hashtbl.t val enable_const_params: t -> bool val enable_unsafe_getters_and_setters: t -> bool @@ -74,6 +75,7 @@ val should_munge_underscores: t -> bool val should_strip_root: t -> bool val suppress_comments: t -> Str.regexp list val suppress_types: t -> SSet.t +val type_graph: t -> Graph_explorer.graph val type_table: t -> (Loc.t, Type.t) Hashtbl.t val verbose: t -> int option @@ -94,6 +96,8 @@ val remove_all_error_suppressions: t -> unit val remove_tvar: t -> Constraint_js.ident -> unit val set_envs: t -> env IMap.t -> unit val set_evaluated: t -> Type.t IMap.t -> unit +val set_type_graph: t -> Graph_explorer.graph -> unit +val set_all_unresolved: t -> Type.TypeSet.t IMap.t -> unit val set_globals: t -> SSet.t -> unit val set_graph: t -> Constraint_js.node IMap.t -> unit val set_in_declare_module: t -> bool -> unit diff --git a/src/typing/debug_js.ml b/src/typing/debug_js.ml index 89b1baea97a..e432a1bf9b7 100644 --- a/src/typing/debug_js.ml +++ b/src/typing/debug_js.ml @@ -215,11 +215,6 @@ and _json_of_t_impl json_cx t = Hh_json.( "assume", _json_of_t json_cx t2 ] - | SpeculativeMatchT (_, attempt, target) -> [ - "attemptType", _json_of_t json_cx attempt; - "targetType", _json_of_use_t json_cx target - ] - | ModuleT (_, {exports_tmap; cjs_export;}) -> let property_maps = Context.property_maps json_cx.cx in let tmap = IMap.find_unsafe exports_tmap property_maps in @@ -237,6 +232,12 @@ and _json_of_t_impl json_cx t = Hh_json.( "type2", _json_of_t json_cx t2 ] + | ChoiceKitT (_, tool) -> [ + "tool", JSON_String (match tool with + | Trigger -> "trigger" + ); + ] + | CustomFunT (_, kind) -> [ "kind", JSON_String (match kind with | ObjectAssign -> "Object.assign" @@ -429,14 +430,6 @@ and _json_of_use_t_impl json_cx t = Hh_json.( "type2", _json_of_t json_cx t2 ] - | ConcretizeLowerT (l, todo_list, done_list, u) - | ConcretizeUpperT (l, todo_list, done_list, u) -> [ - "lowerType", _json_of_t json_cx l; - "todoTypes", JSON_Array (List.map (_json_of_t json_cx) todo_list); - "doneTypes", JSON_Array (List.map (_json_of_t json_cx) done_list); - "upperType", _json_of_use_t json_cx u - ] - | GetKeysT (_, t) -> [ "type", _json_of_t json_cx t ] @@ -507,6 +500,21 @@ and _json_of_use_t_impl json_cx t = Hh_json.( | ReactCreateElementT (_, t, t_out) -> [ "config", _json_of_t json_cx t; "returnType", _json_of_t json_cx t_out; + ] + + | ChoiceKitUseT (_, tool) -> [ + "tool", JSON_String (match tool with + | FullyResolveType _ -> "fullyResolveType" + | TryFlow _ -> "tryFlow" + ); + ] + + | IntersectionPreprocessKitT (_, tool) -> [ + "tool", JSON_String (match tool with + | ConcretizeTypes _ -> "concretizeTypes" + | SentinelPropTest _ -> "sentinelPropTest" + | PropExistsTest _ -> "propExistsTest" + ); ] | SentinelPropTestT (l, sense, sentinel, result) -> [ @@ -724,6 +732,7 @@ and json_of_pred_impl json_cx p = Hh_json.( "right", json_of_pred json_cx r ] | NotP p -> ["pred", json_of_pred json_cx p] + | LeftP (b, t) | RightP (b, t) -> [ "binaryTest", json_of_binary_test json_cx b; @@ -941,7 +950,6 @@ and dump_t_ (depth, tvars) cx t = in let kid = dump_t_ (depth-1, tvars) cx in - let use_kid = dump_use_t_ (depth-1, tvars) cx in let tvar id = if ISet.mem id tvars then spf "%d, ^" id else @@ -1017,8 +1025,6 @@ and dump_t_ (depth, tvars) cx t = (String.concat "; " (List.map kid (InterRep.members rep)))) t | UnionT (_, rep) -> p ~extra:(spf "[%s]" (String.concat "; " (List.map kid (UnionRep.members rep)))) t - | SpeculativeMatchT (_, l, next) -> p - ~extra:(spf "%s, %s" (kid l) (use_kid next)) t | AnyWithLowerBoundT arg | AnyWithUpperBoundT arg -> p ~reason:false ~extra:(kid arg) t | AnyObjT _ @@ -1033,6 +1039,7 @@ and dump_t_ (depth, tvars) cx t = | ExtendsT (nexts, l, u) -> p ~reason:false ~extra:(spf "[%s], %s, %s" (String.concat "; " (List.map kid nexts)) (kid l) (kid u)) t | CustomFunT _ -> p t + | ChoiceKitT _ -> p t and dump_use_t ?(depth=3) cx t = dump_use_t_ (depth, ISet.empty) cx t @@ -1098,8 +1105,6 @@ and dump_use_t_ (depth, tvars) cx t = | HasOwnPropT _ | HasPropT _ | ElemT _ - | ConcretizeLowerT _ - | ConcretizeUpperT _ | ImportModuleNsT _ | ImportDefaultT _ | ImportNamedT _ @@ -1113,7 +1118,9 @@ and dump_use_t_ (depth, tvars) cx t = | DebugPrintT _ | TupleMapT _ | ReactCreateElementT _ - | SentinelPropTestT _ -> + | SentinelPropTestT _ + | IntersectionPreprocessKitT _ + | ChoiceKitUseT _ -> p t let dump_reason cx reason = if Context.should_strip_root cx diff --git a/src/typing/flow_error.ml b/src/typing/flow_error.ml index 24bdb70ef53..733ee4c51e0 100644 --- a/src/typing/flow_error.ml +++ b/src/typing/flow_error.ml @@ -44,9 +44,23 @@ module Impl : sig (* speculative checking *) exception SpeculativeError of Errors.error - val set_speculative: unit -> unit + + (* Maintain a stack of speculative branches. See Speculation for the contents + of the "branch" data structure. + + When speculating (i.e., when this stack is non-empty), some things are + handled differently: + + (1) flow and unify actions on unresolved tvars are deferred + (2) any errors cause short-cutting + *) + val set_speculative: Speculation.branch -> unit val restore_speculative: unit -> unit - val speculation_depth: unit -> int + val speculating: unit -> bool + + (* decide whether an action should be deferred. + when speculating, actions that involve unresolved tvars are deferred. *) + val defer_action: Context.t -> Speculation.Action.t -> bool (* error info is a location followed by a list of strings. mk_info takes location and first string from a reason. *) @@ -108,13 +122,17 @@ end = struct exception SpeculativeError of Errors.error - let speculative = ref 0 - let set_speculative () = speculative := !speculative + 1 - let restore_speculative () = speculative := !speculative - 1 - let speculation_depth () = !speculative + let speculations = ref [] + let set_speculative branch = + speculations := branch::!speculations + let restore_speculative () = + speculations := List.tl !speculations + let speculating () = !speculations <> [] - (* internal *) - let throw_on_error () = !speculative > 0 + let defer_action cx action = + speculating() && + let branch = List.hd !speculations in + Speculation.defer_if_relevant cx branch action let mk_info reason extra_msgs = loc_of_reason reason, desc_of_reason reason :: extra_msgs @@ -125,7 +143,7 @@ end = struct (* lowish-level error logging. basic filtering and packaging before sending error to context. *) let add_output cx error = - if throw_on_error () + if speculating () then raise (SpeculativeError error) else ( if Context.is_verbose cx diff --git a/src/typing/flow_js.ml b/src/typing/flow_js.ml index e788a4aa602..3252639aa49 100644 --- a/src/typing/flow_js.ml +++ b/src/typing/flow_js.ml @@ -327,6 +327,7 @@ let types_of constraints = (* Def types that describe the solution of a type variable. *) let possible_types cx id = types_of (find_graph cx id) + |> List.filter is_proper_def let possible_types_of_type cx = function | OpenT (_, id) -> possible_types cx id @@ -558,18 +559,13 @@ let fresh_context metadata file module_name = (***********************) module ImplicitTypeArgument = struct - (* helpers *) - let add_typeparam_prefix s = spf "type parameter%s" s - let has_typeparam_prefix s = - (String.length s) >= 14 && (String.sub s 0 14) = "type parameter" - (* Make a type argument for a given type parameter, given a reason. Note that not all type arguments are tvars; the following function is used only when polymorphic types need to be implicitly instantiated, because there was no explicit instantiation (via a type application), or when we want to cache a unique instantiation and unify it with other explicit instantiations. *) let mk_targ cx (typeparam, reason_op) = - let prefix_desc = add_typeparam_prefix (spf " `%s` of " typeparam.name) in + let prefix_desc = typeparam_prefix (spf " `%s` of " typeparam.name) in mk_tvar cx (prefix_reason prefix_desc reason_op) (* Abstract a type argument that is created by implicit instantiation @@ -688,10 +684,10 @@ end *) module Cache = struct - module TypePairSet : Set.S with type elt = TypeTerm.t * TypeTerm.use_t = + type type_pair = TypeTerm.t * TypeTerm.use_t + module TypePairSet : Set.S with type elt = type_pair = Set.Make (struct - type elt = TypeTerm.t * TypeTerm.use_t - type t = elt + type t = type_pair let compare = Pervasives.compare end) @@ -745,6 +741,223 @@ module Cache = struct end +(* Helper module for full type resolution as needed to check union and + intersection types. + + Given a type, we walk it to collect the parts of it we wish to resolve. Once + these parts are resolved, they must themselves be walked to collect further + parts to resolve, and so on. In other words, type resolution jobs are created + and processed in rounds, moving closer and closer to full resolution of the + original type. Needless to say, these jobs can be recursive, and so must be + managed carefully for termination and performance. The job management itself + is done in Graph_explorer. (The jobs are naturally modeled as a graph with + dynamically created nodes and edges.) + + Here, we define the function that creates a single round of such jobs. +*) + +module ResolvableTypeJob = struct + + (* A datatype describing type resolution jobs. + + We unfold types as we go, looking for parts that cannot be unfolded + immediately (thus needing resolution to proceed). + + The handling of these parts involve calls to `flow` and `unify`, and is + thus decoupled from the walker itself for clarity. Here, we just create + different jobs for different parts encountered. These jobs are further + processed by bindings_of_jobs. + + Briefly, jobs are created for the following cases. (1) Annotation sources + need to be resolved. (2) So do heads of type applications. (3) Resolved + tvars are recursively unfolded, but we need to remember which resolved + tvars have been unfolded to prevent infinite unfolding. (4) Unresolved + tvars are handled differently based on context: when they are expected + (e.g., when they are part of inferred types), they are logged; when they + are unexpected (e.g., when they are part of annotations), they are + converted to `any`. For more details see bindings_of_jobs. + + *) + type t = + | Binding of Type.t + | OpenResolved + | OpenUnresolved of int option * Type.t + + (* log_unresolved is a mode that determines whether to log unresolved tvars: + it is None when resolving annotations, and Some speculation_id when + resolving inferred types. *) + let rec collect_of_types ?log_unresolved cx reason = + List.fold_left (collect_of_type ?log_unresolved cx reason) + + and collect_of_type ?log_unresolved cx reason acc = function + | OpenT (r, id) as tvar -> + if IMap.mem id acc then acc + else if is_constant_property_reason r + (* It is important to consider reads of constant property names as fully + resolvable, especially since constant property names are often used to + store literals that serve as tags for disjoint unions. Unfortunately, + today we cannot distinguish such reads from others, so we rely on a + common style convention to recognize constant property names. For now + this hack pays for itself: we do not ask such reads to be annotated + with the corresponding literal types to decide membership in those + disjoint unions. *) + then IMap.add id (Binding tvar) acc + else begin match find_graph cx id with + | Resolved t -> + let acc = IMap.add id OpenResolved acc in + collect_of_type ?log_unresolved cx reason acc t + | Unresolved _ -> + if is_instantiable_reason r || is_instantiable_reason reason + (* Instantiable reasons indicate unresolved tvars that are created + "fresh" for the sole purpose of binding to other types, e.g. as + instantiations of type parameters or as existentials. Constraining + them during speculative matching typically do not cause side effects + across branches, and help make progress. *) + then acc + else IMap.add id (OpenUnresolved (log_unresolved, tvar)) acc + end + + | AnnotT (_, source) -> + let _, id = open_tvar source in + if IMap.mem id acc then acc + else IMap.add id (Binding source) acc + + | ThisTypeAppT (poly_t, _, targs) + | TypeAppT (poly_t, targs) + -> + begin match poly_t with + | OpenT (_, id) -> + if IMap.mem id acc then + collect_of_types ?log_unresolved cx reason acc targs + else begin + let acc = IMap.add id (Binding poly_t) acc in + collect_of_types ?log_unresolved cx reason acc targs + end + + | _ -> + let ts = poly_t::targs in + collect_of_types ?log_unresolved cx reason acc ts + end + + (* Some common kinds of types are quite overloaded: sometimes they correspond + to types written by the user, but sometimes they also model internal types, + and as such carry other bits of information. For now, we walk only some + parts of these types. These parts are chosen such that they directly + correspond to parts of the surface syntax of types. It is less clear what + it means to resolve other "internal" parts of these types. In theory, + ignoring them *might* lead to bugs, but we've not seen examples of such + bugs yet. Leaving further investigation of this point as future work. *) + + | ObjT (_, { props_tmap; _ }) -> + let props_tmap = find_props cx props_tmap in + let ts = SMap.fold (fun x t ts -> + if is_internal_name x then ts (* avoid resolving types of shadow properties *) + else t::ts + ) props_tmap [] in + collect_of_types ?log_unresolved cx reason acc ts + | FunT (_, _, _, { params_tlist; return_t; _ }) -> + let ts = return_t :: params_tlist in + collect_of_types ?log_unresolved cx reason acc ts + | ArrT (_, elem_t, ts) -> + let ts = elem_t::ts in + collect_of_types ?log_unresolved cx reason acc ts + | InstanceT (_, static, super, + { class_id; type_args; fields_tmap; methods_tmap; _ }) -> + let ts = if class_id = 0 then [] else [super; static] in + let ts = SMap.fold (fun _ t ts -> t::ts) type_args ts in + let props_tmap = SMap.union + (find_props cx fields_tmap) (find_props cx methods_tmap) in + let ts = SMap.fold (fun _ t ts -> t::ts) props_tmap ts in + collect_of_types ?log_unresolved cx reason acc ts + | PolyT (_, t) -> + collect_of_type ?log_unresolved cx reason acc t + | BoundT _ -> + acc + + (* TODO: The following kinds of types are not walked out of laziness. It's not + immediately clear what we'd gain (or lose) by walking them. *) + + | EvalT _ + | ChoiceKitT (_, _) + | ModuleT (_, _) + | ExtendsT (_, _, _) + -> + acc + + (* The following cases exactly follow Type_visitor (i.e., they do the standard + walk). TODO: Rewriting this walker as a subclass of Type_visitor would be + quite nice (as long as we confirm that the resulting virtualization of + calls to this function doesn't lead to perf degradation: this function is + expected to be quite hot). *) + + | OptionalT t | MaybeT t | RestT t -> + collect_of_type ?log_unresolved cx reason acc t + | UnionT (_, rep) -> + let ts = UnionRep.members rep in + collect_of_types ?log_unresolved cx reason acc ts + | IntersectionT (_, rep) -> + let ts = InterRep.members rep in + collect_of_types ?log_unresolved cx reason acc ts + + | AnyWithUpperBoundT t + | AnyWithLowerBoundT t + | AbstractT t + -> + collect_of_type ?log_unresolved cx reason acc t + + | TypeT (_, t) + | ClassT t + | ThisClassT t + -> + collect_of_type ?log_unresolved cx reason acc t + + | KeysT (_, t) -> + collect_of_type ?log_unresolved cx reason acc t + + | ShapeT (t) -> + collect_of_type ?log_unresolved cx reason acc t + + | DiffT (t1, t2) -> + let ts = [t1;t2] in + collect_of_types ?log_unresolved cx reason acc ts + + | FunProtoBindT _ + | FunProtoCallT _ + | FunProtoApplyT _ + | FunProtoT _ + | CustomFunT (_, _) + | BoolT _ + | NumT _ + | StrT _ + | VoidT _ + | NullT _ + | EmptyT _ + | MixedT _ + | AnyT _ + | TaintT _ + | AnyObjT _ + | AnyFunT _ + | SingletonBoolT _ + | SingletonNumT _ + | SingletonStrT _ + | ExistsT _ + -> + acc + + (* TODO: Support for use types is currently sketchy. Full resolution of use + types are only needed for choice-making on intersections. We care about + calls in particular because one of the biggest uses of intersections is + function overloading. More uses will be added over time. *) + let collect_of_use ~log_unresolved cx reason acc = function + | UseT (_, t) -> + collect_of_type ~log_unresolved cx reason acc t + | CallT (_, ft) -> + collect_of_types ~log_unresolved cx reason acc + (ft.params_tlist @ [ft.return_t]) + | _ -> acc + +end + (*********************************************************************) (********************) @@ -782,9 +995,18 @@ let not_expect_bound t = match t with | BoundT _ -> assert_false (spf "Did not expect %s" (string_of_ctor t)) | _ -> () -let not_expect_use_bound t = +let not_expect_bound_use t = lift_to_use not_expect_bound t +(* Sometimes we expect to see only proper def types. Proper def types make sense + as use types. *) +let expect_proper_def t = + if not (is_proper_def t) then + assert_false (spf "Did not expect %s" (string_of_ctor t)) + +let expect_proper_def_use t = + lift_to_use expect_proper_def t + (********************** start of slab **********************************) (** NOTE: Do not call this function directly. Instead, call the wrapper @@ -814,7 +1036,16 @@ let rec __flow cx ((l: Type.t), (u: Type.use_t)) trace = (* Type parameters should always be substituted out, and as such they should never appear "exposed" in flows. (They can still appear bound inside polymorphic definitions.) *) - not_expect_bound l; not_expect_use_bound u; + not_expect_bound l; not_expect_bound_use u; + (* Types that are classified as def types but don't make sense as use types + should not appear as use types. *) + expect_proper_def_use u; + + (* Before processing the flow action, check that it is not deferred. If it + is, then when speculation is complete, the action either fires or is + discarded depending on whether the case that created the action is + selected or not. *) + if not (defer_action cx (Speculation.Action.Flow (l, u))) then match (l,u) with @@ -872,17 +1103,74 @@ let rec __flow cx ((l: Type.t), (u: Type.use_t)) trace = rec_flow cx trace (t1, UseT (use_op, t2)) ); - (******************) - (* concretization *) - (******************) + (************************) + (* Full type resolution *) + (************************) + + (* Full resolution of a type involves (1) walking the type to collect a + bunch of unresolved tvars (2) emitting constraints that, once those tvars + are resolved, recursively trigger the process for the resolved types (3) + finishing when no unresolved tvars remain. + + (1) is covered in ResolvableTypeJob. Below, we cover (2) and (3). + + For (2), we emit a FullyResolveType constraint on any unresolved tvar + found by (1). These unresolved tvars are chosen so that they have the + following nice property, called '0->1': they remain unresolved until, at + some point, they are unified with a concrete type. Moreover, the act of + resolution coincides with the appearance of one (the first and the last) + upper bound. (In general, unresolved tvars can accumulate an arbitrary + number of lower and upper bounds over its lifetime.) More details can be + found in bindings_of_jobs. + + For (3), we create a special "goal" tvar that acts like a promise for + fully resolving the original type, and emit a Trigger constraint on the + goal when no more work remains. + + The main client of full type resolution is checking union and + intersection types. The check itself is modeled by a TryFlow constraint, + which is guarded by a goal tvar that corresponds to some full type + resolution requirement. Eventually, this goal is "triggered," which in + turn triggers the check. (The name "TryFlow" refers to the technique used + in the check, which literally tries each branch of the union or + intersection in turn, maintaining some matching state as it goes: see + speculative_matches for details). *) + + | t, ChoiceKitUseT (reason, FullyResolveType id) -> + fully_resolve_type cx reason id t + + | ChoiceKitT (_, Trigger), ChoiceKitUseT (reason, TryFlow (i, spec)) -> + speculative_matches cx trace reason i spec + + (* Intersection types need a preprocessing step before they can be checked; + this step brings it closer to parity with the checking of union types, + where the preprocessing effectively happens "automatically." This + apparent asymmetry is explained in prep_try_intersection. + + Here, it suffices to note that the preprocessing step involves + concretizing some types. Type concretization is distinct from full type + resolution. Whereas full type resolution is a recursive process that + needs careful orchestration, type concretization is a relatively simple + one-step process: a tvar is concretized when any lower bound appears on + it. Also, unlike full type resolution, the tvars that are concretized + don't necessarily have the 0->1 property: they could be concretized at + different types, as more and more lower bounds appear. *) + + | UnionT (_, urep), IntersectionPreprocessKitT (reason, + ConcretizeTypes (unresolved, resolved, IntersectionT (r, rep), u)) -> + UnionRep.members urep |> List.iter (fun t -> + rec_flow cx trace (t, IntersectionPreprocessKitT (reason, + ConcretizeTypes (unresolved, resolved, IntersectionT (r, rep), u))) + ) - (** pairs emitted by in-progress concretize_parts *) - | t, ConcretizeLowerT (l, todo_ts, done_ts, u) -> - concretize_lower_parts cx trace l u (t :: done_ts) todo_ts + | AnnotT (_, source_t), IntersectionPreprocessKitT (reason, + ConcretizeTypes (unresolved, resolved, IntersectionT (r, rep), u)) -> + rec_flow cx trace (source_t, IntersectionPreprocessKitT (reason, + ConcretizeTypes (unresolved, resolved, IntersectionT (r, rep), u))) - (** pairs emitted by in-progress concretize_parts *) - | t, ConcretizeUpperT (l, todo_ts, done_ts, u) -> - concretize_upper_parts cx trace l u (t :: done_ts) todo_ts + | t, IntersectionPreprocessKitT (reason, + ConcretizeTypes (unresolved, resolved, IntersectionT (r, rep), u)) -> + prep_try_intersection cx trace reason unresolved (resolved @ [t]) u r rep (*****************) (* destructuring *) @@ -933,9 +1221,9 @@ let rec __flow cx ((l: Type.t), (u: Type.use_t)) trace = (* The sink component of an annotation constrains values flowing into the annotated site. *) - | _, UseT (use_op, AnnotT (sink_t, _)) -> - let reason = reason_of_t sink_t in - rec_flow cx trace (sink_t, ReposUseT (reason, use_op, l)) + | _, UseT (use_op, AnnotT (_, source_t)) -> + let reason = reason_of_t source_t in + rec_flow cx trace (source_t, ReposUseT (reason, use_op, l)) (* The source component of an annotation flows out of the annotated site to downstream uses. *) @@ -964,6 +1252,32 @@ let rec __flow cx ((l: Type.t), (u: Type.use_t)) trace = | (_, UnifyT(t,t_other)) -> rec_unify cx trace t t_other + (*****************************************************************) + (* Intersection type preprocessing for certain object predicates *) + (*****************************************************************) + + (* Predicate refinements on intersections of object types need careful + handling. An intersection of object types passes a predicate when any of + those object types passes the predicate: however, the refined type must + be the intersection as a whole, not the particular object type that + passes the predicate! (For example, we may check some condition on + property x and property y of { x: ... } & { y: ... } in sequence, and not + expect to get property-not-found errors in the process.) + + Although this seems like a special case, it's not. An intersection of + object types should behave more or less the same as a "concatenated" + object type with all the properties of those object types. The added + complication arises as an implementation detail, because we do not + concatenate those object types explicitly. *) + + | _, IntersectionPreprocessKitT (_, + SentinelPropTest (sense, key, t, inter, tvar)) -> + sentinel_prop_test_generic key cx trace tvar inter (sense, l, t) + + | _, IntersectionPreprocessKitT (_, + PropExistsTest (sense, key, inter, tvar)) -> + prop_exists_test_generic key cx trace tvar inter sense l + (*********************************************************************) (* `import type` creates a properly-parameterized type alias for the *) (* remote type -- but only for particular, valid remote types. *) @@ -1521,6 +1835,9 @@ let rec __flow cx ((l: Type.t), (u: Type.use_t)) trace = let t_out = mk_instance cx reason_op ~for_type:false c in rec_flow cx trace (l, UseT (use_op, t_out)) + | TypeAppT _, ReposLowerT (reason_op, u) -> + rec_flow cx trace (reposition cx reason_op l, u) + | (TypeAppT(c,ts), MethodT _) -> let reason_op = reason_of_use_t u in let reason_tapp = reason_of_t l in @@ -1760,30 +2077,6 @@ let rec __flow cx ((l: Type.t), (u: Type.use_t)) trace = when List.mem u (InterRep.members rep) -> () - (** To check that the concrete type l may flow to UnionT(_, ts), we try each - type in ts in turn. The types in ts may be type variables, but by - routing them through SpeculativeMatchT, we ensure that they are - tried only when their concrete uses are available. The different - branches of unions are assumed to be disjoint at the top level, so that - it is always sound to pick the first type in ts that matches the type - l. *) - - (** pairs emitted by try_union: - UnionT has been partitioned into head_u (head member) - and tail_u (union of tail members) *) - | SpeculativeMatchT(_, l, tail_u), head_u -> - begin match speculative_match cx trace l head_u with - | None -> () - | Some err -> - (* rec_flow cx trace (l, tail_u) *) - let tail_u = match tail_u with - | UseT (use_op, UnionT (r, rep)) -> - (* record this error *) - UseT (use_op, UnionT (r, UnionRep.record_error err rep)) - | _ -> tail_u - in rec_flow cx trace (l, tail_u) - end - | _, UseT (use_op, UnionT (r, rep)) -> ( match UnionRep.quick_mem l rep with | Some true -> () @@ -1794,7 +2087,10 @@ let rec __flow cx ((l: Type.t), (u: Type.use_t)) trace = in rec_flow cx trace (l, UseT (use_op, EmptyT r)) | None -> - try_union cx trace l r rep + (* Try the branches of the union in turn, with the goal of selecting the + correct branch. This process is reused for intersections as well. See + comments on try_union and try_intersection. *) + try_union cx l r rep ) (* maybe and optional types are just special union types *) @@ -1805,31 +2101,6 @@ let rec __flow cx ((l: Type.t), (u: Type.use_t)) trace = | (t1, UseT (use_op, OptionalT(t2))) -> rec_flow cx trace (t1, UseT (use_op, t2)) - (** To check that IntersectionT(_, ts) may flow to the concrete type u, we - try each type in ts in turn. The types in ts may be type variables, but - by routing them through SpeculativeMatchT, we ensure that they - are tried only when their concrete definitionss are available. Note that - unlike unions, the different branches of intersections are usually not - distinct at the top level (e.g., they may all be function types, or - object types): instead, they are assumed to be disjoint in their parts, - so we must suffiently concretize parts of u to make the disjointness - evident when the different branches are tried; see below. *) - - (** pairs emitted by try_intersection: - IntersectionT has been partitioned into head_l (head member) - and tail_l (intersection of tail members) *) - | head_l, UseT (_, SpeculativeMatchT (_, tail_l, u)) -> ( - match speculative_match cx trace head_l u with - | None -> () - | Some err -> - let tail_l = match tail_l with - | IntersectionT (r, rep) -> - (* record this error *) - IntersectionT (r, InterRep.record_error err rep) - | _ -> tail_l - in rec_flow cx trace (tail_l, u) - ) - (** special treatment for some operations on intersections: these rules fire for particular UBs whose constraints can (or must) be resolved against intersection LBs as a whole, instead of @@ -1881,8 +2152,8 @@ let rec __flow cx ((l: Type.t), (u: Type.use_t)) trace = ); rec_flow cx trace (l, UseT (use_op, proto_t)) - (** predicates: prevent a predicate UB from prematurely - decomposing an intersection LB *) + (** predicates: prevent a predicate upper bound from prematurely decomposing + an intersection lower bound *) | IntersectionT _, PredicateT (pred, tout) -> predicate cx trace tout (l, pred) @@ -1898,25 +2169,18 @@ let rec __flow cx ((l: Type.t), (u: Type.use_t)) trace = | IntersectionT _, ReposLowerT (reason_op, u) -> rec_flow cx trace (reposition cx reason_op l, u) - (** All other pairs with an intersection LB come here. - Before processing, we ensure that both the UB target and - the intersection LB are concretized. Each of these steps - is a recursion, and the concretization may result in other - rules (eg the special cases above) firing. If none do, then - we'll wind up back here with a fully concretized pair, at - which point we begin the speculative match process via - try_intersection. *) + (** All other pairs with an intersection lower bound come here. Before + further processing, we ensure that the upper bound is concretized. See + prep_try_intersection for details. **) + + (* (After the above preprocessing step, try the branches of the intersection + in turn, with the goal of selecting the correct branch. This process is + reused for unions as well. See comments on try_union and + try_intersection.) *) | IntersectionT (r, rep), u -> - let upper_parts = upper_parts_to_concretize cx u in - if upper_parts <> [] - then concretize_upper_parts cx trace l u [] upper_parts - else ( - let lower_parts = lower_parts_to_concretize cx l in - if lower_parts <> [] - then concretize_lower_parts cx trace l u [] lower_parts - else try_intersection cx trace u r rep - ) + prep_try_intersection cx trace + (reason_of_use_t u) (parts_to_replace u) [] u r rep (* singleton lower bounds are equivalent to the corresponding primitive with a literal constraint. These conversions are @@ -2277,7 +2541,11 @@ let rec __flow cx ((l: Type.t), (u: Type.use_t)) trace = if lit then ( (* prop from unaliased LB: check <:, then make exact *) rec_flow cx trace (lt, UseT (use_op, ut)); - write_prop cx lflds s ut + (* Band-aid to avoid side effect in speculation mode. Even in + non-speculation mode, the side effect here is racy, so it either + needs to be taken out or replaced with something more + robust. Tracked by #11299251. *) + if not (speculating ()) then write_prop cx lflds s ut ) else ( (* prop from aliased LB must be exact *) rec_unify cx trace lt ut @@ -2293,7 +2561,11 @@ let rec __flow cx ((l: Type.t), (u: Type.use_t)) trace = an optional property, as well as ensuring compatibility with dictionary constraints if present *) dictionary cx trace (string_key s ureason) t ldict; - write_prop cx lflds s ut; + (* Band-aid to avoid side effect in speculation mode. Even in + non-speculation mode, the side effect here is racy, so it either + needs to be taken out or replaced with something more + robust. Tracked by #11299251. *) + if not (speculating ()) then write_prop cx lflds s ut; | _ -> (* otherwise, we ensure compatibility with dictionary constraints if present, and look up the property in the prototype *) @@ -3964,6 +4236,7 @@ and subst cx ?(force=true) (map: Type.t SMap.t) t = | FunProtoApplyT _ | FunProtoBindT _ | FunProtoCallT _ + | ChoiceKitT _ | CustomFunT _ -> t @@ -4156,7 +4429,6 @@ and subst cx ?(force=true) (map: Type.t SMap.t) t = | SingletonBoolT _ | SingletonStrT _ -> t - | SpeculativeMatchT _ | ModuleT _ | ExtendsT _ -> @@ -4272,7 +4544,6 @@ and check_polarity cx polarity = function | AnnotT _ | ShapeT _ | DiffT _ - | SpeculativeMatchT _ | KeysT _ | FunProtoT _ | FunProtoApplyT _ @@ -4280,6 +4551,7 @@ and check_polarity cx polarity = function | FunProtoCallT _ | EvalT _ | ExtendsT _ + | ChoiceKitT _ | CustomFunT _ -> () (* TODO *) @@ -4474,13 +4746,372 @@ and chain_objects cx ?trace reason this those = ) ) this those -(* Speculatively match types, returning success. *) -and speculative_match cx trace l u = +(*******************************************************) +(* Entry points into the process of trying different *) +(* branches of union and intersection types. *) +(*******************************************************) + +(* The problem we're trying to solve here is common to checking unions and + intersections: how do we make a choice between alternatives, when (i) we have + only partial information (i.e., while we're in the middle of type inference) + and when (ii) we want to avoid regret (i.e., by not committing to an + alternative that might not work out, when alternatives that were not + considered could have worked out)? + + To appreciate the problem, consider what happens without choice. Partial + information is not a problem: we emit constraints that must be satisfied for + something to work, and either those constraints fail (indicating a problem) + or they don't fail (indicating no problem). With choice and partial + information, we cannot naively emit constraints as we try alternatives + *without also having a mechanism to roll back those constraints*. This is + because those constraints don't *have* to be satisfied; some other + alternative may end up not needing those constraints to be satisfied for + things to work out! + + It is not too hard to imagine scary scenarios we can get into without a + roll-back mechanism. (These scenarios are not theoretical, by the way: with a + previous implementation of union and intersection types that didn't + anticipate these scenarios, they consistently caused a lot of problems in + real-world use cases.) + + * One bad state we can get into is where, when trying an alternative, we emit + constraints hoping they would be satisfied, and they appear to work. So we + commit to that particular alternative. Then much later find out that those + constraints are unsatified, at which point we have lost the ability to try + other alternatives that could have worked. This leads to a class of bugs + where a union or intersection type contains cases that should have worked, + but they don't. + + * An even worse state we can get into is where we do discover that an + alternative won't work out while we're still in a position of choosing + another alternative, but in the process of making that discovery we emit + constraints that linger on in a ghost-like state. Meanwhile, we pick another + alternative, it works out, and we move on. Except that much later the ghost + constraints become unsatisfied, leading to much confusion on the source of + the resulting errors. This leads to a class of bugs where we get spurious + errors even when a union or intersection type seems to have worked. + + So, we just implement roll-back, right? Basically...yes. But rolling back + constraints is really hard in the current implementation. Instead, we try to + avoid processing constraints that have side effects as much as possible while + trying alternatives: by ensuring that (1) we don't (need to) emit too many + constraints that have side effects (2) those that we do emit get deferred, + instead of being processed immediately, until a choice can be made, thereby + not participating in the choice-making process. + + (1) How do we ensure we don't emit too many constraints that have side + effects? By fully resolving types before they participate in the + choice-making process. Basically, we want to have as much information as we + can before trying alternatives. It is a nice property of our implementation + that once types are resolved, constraints emitted against them don't have + (serious) side effects: they get simplified and simplified until we either + hit success or failure. The details of this process is described in + ResolvableTypeJob and in resolve_bindings. + + (2) But not all types can be fully resolved. In particular, while union and + intersection types themselves can be fully resolved, the lower and upper + bounds we check them against could have still-to-be-inferred types in + them. How do we ensure that for the potentially side-effectful constraints we + do emit on these types, we avoid undue side effects? By explicitly marking + these types as unresolved, and deferring the execution of constraints that + involved such marked types until a choice can be made. The details of this + process is described in Speculation. + + There is a necessary trade-off in the approach. In particular, (2) means that + sometimes choices cannot be made: it is ambiguous which constraints should be + executed when trying different alternatives. We detect such ambiguities + (conservatively, but only when a best-effort choice-making strategy doesn't + work), and ask for additional annotations to disambiguate the relevant + alternatives. A particularly nice property of this approach is that it is + complete: with enough annotations it is always possible to make a + choice. Another "meta-feature" of this approach is that it leaves room for + incremental improvement: e.g., we would need fewer additional annotations as + we improve our inference algorithm to detect cases where more unresolved + tvars can be fully resolved ahead of time (in other words, detect when they + have the "0->1" property, discussed elsewhere, roughly meaning they are + determined by annotations). +*) + +(** Every choice-making process on a union or intersection type is assigned a + unique identifier, called the speculation_id. This identifier keeps track of + unresolved tvars encountered when trying to fully resolve types. **) + +and try_union cx l reason rep = + let ts = UnionRep.members rep in + let speculation_id = mk_id() in + Speculation.init_speculation cx speculation_id; + + (* collect parts of the union type to be fully resolved *) + let imap = ResolvableTypeJob.collect_of_types cx reason IMap.empty ts in + (* collect parts of the lower bound to be fully resolved, while logging + unresolved tvars *) + let imap = ResolvableTypeJob.collect_of_type + ~log_unresolved:speculation_id cx reason imap l in + (* fully resolve the collected types *) + resolve_bindings_init cx reason (bindings_of_jobs cx imap) @@ + (* ...and then begin the choice-making process *) + try_flow_continuation cx reason speculation_id (UnionCases(l, ts)) + +and try_intersection cx u reason rep = + let ts = InterRep.members rep in + let speculation_id = mk_id() in + Speculation.init_speculation cx speculation_id; + + (* collect parts of the intersection type to be fully resolved *) + let imap = ResolvableTypeJob.collect_of_types cx reason IMap.empty ts in + (* collect parts of the upper bound to be fully resolved, while logging + unresolved tvars *) + let imap = ResolvableTypeJob.collect_of_use + ~log_unresolved:speculation_id cx reason imap u in + (* fully resolve the collected types *) + resolve_bindings_init cx reason (bindings_of_jobs cx imap) @@ + (* ...and then begin the choice-making process *) + try_flow_continuation cx reason speculation_id (IntersectionCases(ts, u)) + +(* Preprocessing for intersection types. + + Before feeding into the choice-making machinery described above, we + preprocess upper bounds of intersection types. This preprocessing seems + asymmetric, but paradoxically, it is not: the purpose of the preprocessing is + to bring choice-making on intersections to parity with choice-making on + unions. + + Consider what happens when a lower bound is checked against a union type. The + lower bound is always concretized before a choice is made! In other words, + even if we emit a flow from an unresolved tvar to a union type, the + constraint fires only when the unresolved tvar has been concretized. + + Now, consider checking an intersection type with an upper bound. As an + artifact of how tvars and concrete types are processed, the upper bound would + appear to be concrete even though the actual parts of the upper bound that + are involved in the choice-making may be unresolved! (These parts are the + top-level input positions in the upper bound, which end up choosing between + the top-level input positions in the members of the intersection type.) If we + did not concretize the parts of the upper bound involved in choice-making, we + would start the choice-making process at a disadvantage (compared to + choice-making with a union type and an already concretized lower + bound). Thus, we do an extra preprocessing step where we collect the parts of + the upper bound to be concretized, and for each combination of concrete types + for those parts, call the choice-making process. +*) + +(** The following function concretizes each tvar in unresolved in turn, + recording their corresponding concrete lower bounds in resolved as it + goes. At each step, it emits a ConcretizeTypes constraint on an unresolved + tvar, which in turn calls into this function when a concrete lower bound + appears on that tvar. **) +and prep_try_intersection cx trace reason unresolved resolved u r rep = + match unresolved with + | [] -> try_intersection cx (replace_parts resolved u) r rep + | tvar::unresolved -> + rec_flow cx trace (tvar, intersection_preprocess_kit reason + (ConcretizeTypes (unresolved, resolved, IntersectionT (r, rep), u))) + +(* some patterns need to be concretized before proceeding further *) +and patt_that_needs_concretization = function + | OpenT _ | UnionT _ | AnnotT _ -> true + | _ -> false + +and concretize_patt replace patt = + snd (List.fold_left (fun (replace, result) t -> + if patt_that_needs_concretization t + then List.tl replace, result@[List.hd replace] + else replace, result@[t] + ) (replace, []) patt) + +(* for now, we only care about concretizating parts of functions and calls *) +and parts_to_replace = function + | UseT (_, FunT (_, _, _, callt)) -> + List.filter patt_that_needs_concretization callt.params_tlist + | CallT (_, callt) -> + List.filter patt_that_needs_concretization callt.params_tlist + | _ -> [] + +and replace_parts replace = function + | UseT (op, FunT (r, t1, t2, callt)) -> + UseT (op, FunT (r, t1, t2, { callt with + params_tlist = concretize_patt replace callt.params_tlist; + })) + | CallT (r, callt) -> + CallT (r, { callt with + params_tlist = concretize_patt replace callt.params_tlist; + }) + | u -> u + +(************************) +(* Full type resolution *) +(************************) + +(* Here we continue where we left off at ResolvableTypeJob. Once we have + collected a set of type resolution jobs, we create so-called bindings from + these jobs. A binding is a (id, tvar) pair, where tvar is what needs to be + resolved, and id is an identifier that serves as an index for that job. + + We don't try to fully resolve unresolved tvars that are not annotation + sources or heads of type applications, since in general they don't satify the + 0->1 property. Instead: + + (1) When we're expecting them, e.g., when we're looking at inferred types, we + mark them so that we can recognize them later, during speculative matching. + + (2) When we're not expecting them, e.g., when we're fully resolving union / + intersection type annotations, we unify them as `any`. Ideally we wouldn't be + worrying about this case, but who knows what cruft we might have accumulated + on annotation types, so just getting that cruft out of the way. + + These decisions were made in ResolvableTypeJob.collect_of_types and are + reflected in the use (or not) of OpenUnresolved (see below). +*) + +and bindings_of_jobs cx jobs = + IMap.fold ResolvableTypeJob.(fun id job bindings -> match job with + | OpenResolved -> bindings + | Binding t -> (id, t)::bindings + | OpenUnresolved (log_unresolved, t) -> + begin match log_unresolved with + | Some speculation_id -> + Speculation.add_unresolved_to_speculation cx speculation_id t + | None -> + unify cx t AnyT.t + end; + bindings + ) jobs [] + +(* Entry point into full type resolution. Create an identifier for the goal + tvar, and call the general full type resolution function below. *) +and resolve_bindings_init cx reason bindings done_tvar = + let id = create_goal cx done_tvar in + resolve_bindings cx reason id bindings + +and create_goal cx tvar = + let i = mk_id () in + Graph_explorer.node (Context.type_graph cx) i; + Context.set_evaluated cx (IMap.add i tvar (Context.evaluated cx)); + i + +(* Let id be the identifier associated with a tvar that is not yet + resolved. (Here, resolved/unresolved refer to the state of the tvar in the + context graph: does it point to Resolved _ or Unresolved _?) As soon as the + tvar is resolved to some type, we generate some bindings by walking that + type. Full type resolution at id now depends on full resolution of the + ids/tvars in those bindings. The following function ensures that those + dependencies are recorded and processed. + + Dependency management happens in Graph_explorer, using efficient data + structures discussed therein. All we need to do here is to connect id to + bindings in that graph, while taking care that (1) the conditions of adding + edges to the graph are satisfied, and (2) cleaning up the effects of adding + those edges to the graph. Finally (3) we request full type resolution of the + bindings themselves. + + For (1), note that the graph only retains transitively closed dependencies + from one kind of tvars to another kind of tvars. The former kind includes + tvars that are resolved but not yet fully resolved. The latter kind includes + tvars that are not yet resolved. Thus, in particular we must filter out + bindings that correspond to fully resolved tvars (see + is_unfinished_target). On the other hand, the fully_resolve_type function + below already ensures that id is not yet fully resolved (via + is_unexplored_source). + + For (2), after adding edges we might discover that some tvars are now fully + resolved: this happens when, e.g., no new transitively closed dependencies + get added on id, and full type resolution of some tvars depended only on id. + If any of these fully resolved tvars were goal tvars, we trigger them. + + For (3) we emit a ResolveType constraint for each binding; when the + corresponding tvar is resolved, the function fully_resolve_type below is + called, which in turn calls back into this function (thus closing the + recursive loop). +*) + +and resolve_bindings cx reason id bindings = + let bindings = filter_bindings cx bindings in + let fully_resolve_ids = connect_id_to_bindings cx id bindings in + ISet.iter (fun id -> + match IMap.get id (Context.evaluated cx) with + | None -> () + | Some tvar -> trigger cx reason tvar + ) fully_resolve_ids; + List.iter (resolve_binding cx reason) bindings + +and fully_resolve_type cx reason id t = + if is_unexplored_source cx id then + let imap = ResolvableTypeJob.collect_of_type cx reason IMap.empty t in + resolve_bindings cx reason id (bindings_of_jobs cx imap) + +and filter_bindings cx = + List.filter (fun (id, _) -> is_unfinished_target cx id) + +and connect_id_to_bindings cx id bindings = + let ids, _ = List.split bindings in + Graph_explorer.edges (Context.type_graph cx) (id, ids) + +(* Sanity conditions on source and target before adding edges to the + graph. Nodes are in one of three states, described in Graph_explorer: + Not_found (corresponding to unresolved tvars), Found _ (corresponding to + resolved but not yet fully resolved tvars), and Finished (corresponding to + fully resolved tvars). *) + +and is_unexplored_source cx id = + match Graph_explorer.stat_graph id (Context.type_graph cx) with + | Graph_explorer.Finished -> false + | Graph_explorer.Not_found -> false + | Graph_explorer.Found node -> Graph_explorer.is_unexplored_node node + +and is_unfinished_target cx id = + let type_graph = Context.type_graph cx in + match Graph_explorer.stat_graph id type_graph with + | Graph_explorer.Finished -> false + | Graph_explorer.Not_found -> + Graph_explorer.node type_graph id; + true + | Graph_explorer.Found node -> + not (Graph_explorer.is_finished_node node) + +(** utils for creating toolkit types **) + +and choice_kit reason k = + ChoiceKitT (reason, k) + +and choice_kit_use reason k = + ChoiceKitUseT (reason, k) + +and intersection_preprocess_kit reason k = + IntersectionPreprocessKitT (reason, k) + +(** utils for emitting toolkit constraints **) + +and trigger cx reason done_tvar = + flow cx (choice_kit reason Trigger, UseT (UnknownUse, done_tvar)) + +and try_flow_continuation cx reason speculation_id spec = + tvar_with_constraint cx + (choice_kit_use reason (TryFlow (speculation_id, spec))) + +and resolve_binding cx reason (id, t) = + flow cx ( + t, + choice_kit_use reason (FullyResolveType id) + ) + +(************************) +(* Speculative matching *) +(************************) + +(* Speculatively match a pair of types, returning whether some error was + encountered or not. Speculative matching happens in the context of a + particular "branch": this context controls how some constraints emitted + during the matching might be processed. See comments in Speculation for + details on branches. See also speculative_matches, which calls this function + iteratively and processes its results. *) +and speculative_match cx trace branch l u = let ops = Ops.get () in let typeapp_stack = TypeAppExpansion.get () in - set_speculative (); + let cache = !Cache.FlowConstraint.cache in + set_speculative branch; let restore () = restore_speculative (); + Cache.FlowConstraint.cache := cache; TypeAppExpansion.set typeapp_stack; Ops.set ops in @@ -4496,11 +5127,221 @@ and speculative_match cx trace l u = restore (); raise exn -(* try each branch of a union in turn *) -and try_union cx trace l reason rep = - match UnionRep.members rep with - | t :: _ -> - (* embed reasons of consituent types into outer reason *) +(* Speculatively match several alternatives in turn, as presented when checking + a union or intersection type. This process maintains a so-called "match + state" that describes the best possible choice found so far, and can + terminate in various ways: + + (1) One of the alternatives definitely succeeds. This is straightforward: we + can safely discard any later alternatives. + + (2) All alternatives fail. This is also straightforward: we emit an + appropriate error message. + + (3) One of the alternatives looks promising (i.e., it doesn't immediately + fail, but it doesn't immediately succeed either: some potentially + side-effectful constraints, called actions, were emitted while trying the + alternative, whose execution has been deferred), and all the later + alternatives fail. In this scenario, we pick the promising alternative, and + then fire the deferred actions. This is fine, because the choice cannot cause + regret: the chosen alternative was the only one that had any chance of + succeeding. + + (4) Multiple alternatives look promising, but the set of deferred actions + emitted while trying the first of those alternatives form a subset of those + emitted by later trials. Here we pick the first promising alternative (and + fire the deferred actions). The reason this is fine is similar to (3): once + again, the choice cannot cause any regret, because if it failed, then the + later alternatives would have failed too. So the chosen alternative had the + best chance of succeeding. + + (5) But sometimes, multiple alternatives look promising and we really can't + decide which is best. This happens when the set of deferred actions emitted + by them are incomparable, or later trials have more chances of succeeding + than previous trials. Such scenarios typically point to real ambiguities, and + so we ask for additional annotations on unresolved tvars to disambiguate. + + See Speculation for more details on terminology and low-level mechanisms used + here, including what bits of information are carried by match_state and case, + how actions are deferred and diff'd, etc. + + Because this process is common to checking union and intersection types, we + abstract the latter into a so-called "spec." The spec is used to customize + error messages and to ignore unresolved tvars that are deemed irrelevant to + choice-making. +*) +and speculative_matches cx trace r speculation_id spec = Speculation.Case.( + (* extract stuff to ignore while considering actions *) + let ignore = ignore_of_spec spec in + (* split spec into a list of pairs of types to try speculative matching on *) + let trials = trials_of_spec spec in + + let rec loop match_state = function + (* Here match_state can take on various values: + + (a) (NoMatch errs) indicates that everything has failed up to this point, + with errors recorded in errs. Note that the initial value of acc is + Some (NoMatch []). + + (b) (ConditionalMatch case) indicates the a promising alternative has + been found, but not chosen yet. + *) + | [] -> return match_state + + | (case_id, case_r, l, u)::trials -> + let case = { case_id; unresolved = TypeSet.empty; actions = []} in + (* speculatively match the pair of types in this trial *) + let error = speculative_match cx trace + { Speculation.ignore; speculation_id; case } l u in + match error with + | None -> + (* no error, looking great so far... *) + begin match match_state with + | Speculation.NoMatch _ -> + (* everything had failed up to this point. so no ambiguity yet... *) + if TypeSet.is_empty case.unresolved + (* ...and no unresolved tvars encountered during the speculative + match! This is great news. It means that this alternative will + definitely succeed. Fire any deferred actions and short-cut. *) + then fire_actions cx trace case.actions + (* Otherwise, record that we've found a promising alternative. *) + else loop (Speculation.ConditionalMatch case) trials + + | Speculation.ConditionalMatch prev_case -> + (* umm, there's another previously found promising alternative *) + (* so compute the difference in side effects between that alternative + and this *) + let ts = diff prev_case case in + (* if the side effects of the previously found promising alternative + are fewer, then keep holding on to that alternative *) + if ts = [] then loop match_state trials + (* otherwise, we have an ambiguity; blame the unresolved tvars and + short-cut *) + else begin + let prev_case_id = prev_case.case_id in + let cases = choices_of_spec spec in + blame_unresolved cx trace prev_case_id case_id cases case_r r ts + end + end + | Some err -> + (* if an error is found, then throw away this alternative... *) + begin match match_state with + | Speculation.NoMatch errs -> + (* ...adding to the error list if no promising alternative has been + found yet *) + loop (Speculation.NoMatch (err::errs)) trials + | _ -> loop match_state trials + end + + and return = function + | Speculation.ConditionalMatch case -> + (* best choice that survived, congrats! fire deferred actions *) + fire_actions cx trace case.actions + | Speculation.NoMatch errs -> + (* everything failed; make a really detailed error message listing out the + error found for each alternative *) + let ts = choices_of_spec spec in + let errs = List.rev errs in + assert (List.length ts = List.length errs); + let extra = List.(combine ts errs) |> List.mapi ( + fun i (t, err) -> + let header_infos = [ + Loc.none, [spf "Member %d:" (i + 1)]; + info_of_reason (reason_of_t t); + Loc.none, ["Error:"]; + ] in + let error_infos, error_extra = Errors.( + infos_of_error err, extra_of_error err + ) in + let info_list = header_infos @ error_infos in + let info_tree = match error_extra with + | [] -> Errors.InfoLeaf (info_list) + | _ -> Errors.InfoNode (info_list, error_extra) + in + info_tree + ) in + let l,u = match spec with + | UnionCases (l, us) -> + let r = mk_union_reason r us in + l, UseT (UnknownUse, UnionT (r, UnionRep.empty)) + + | IntersectionCases (ls, u) -> + let r = mk_intersection_reason r ls in + IntersectionT (r, InterRep.empty), u + in + flow_err cx trace (err_msg l u) ~extra l u + + in loop (Speculation.NoMatch []) trials +) + +(* Make an informative error message that points out the ambiguity, and where + additional annotations can help disambiguate. Recall that an ambiguity + arises precisely when: + + (1) one alternative looks promising, but has some chance of failing + + (2) a later alternative also looks promising, and has some chance of not + failing even if the first alternative fails + + ...with the caveat that "looks promising" and "some chance of failing" are + euphemisms for some pretty conservative approximations made by Flow when it + encounters potentially side-effectful constraints involving unresolved tvars + during a trial. +*) +and blame_unresolved cx trace prev_i i cases case_r r ts = + let infos = ts |> List.map (fun t -> + rec_unify cx trace t AnyT.t; + info_of_reason (reason_of_t t) + ) in + let prev_case = reason_of_t (List.nth cases prev_i) in + let case = reason_of_t (List.nth cases i) in + let extra = [ + Errors.InfoLeaf [ + Loc.none, [spf "Case %d may work:" (prev_i + 1)]; + info_of_reason prev_case; + ]; + Errors.InfoLeaf [ + Loc.none, [spf "But if it doesn't, case %d looks promising too:" (i + 1)]; + info_of_reason case; + ]; + Errors.InfoLeaf ( + (Loc.none, + [spf "Please provide additional annotation(s) to determine whether case %d works \ +(or consider merging it with case %d):" + (prev_i + 1) + (i + 1) + ]):: + infos + ) + ] in + add_extended_error cx ~extra [ + (mk_info case_r + ["Could not decide which case to select"]); + (info_of_reason r) + ] + +and trials_of_spec = function + | UnionCases (l, us) -> + List.mapi (fun i u -> (i, reason_of_t l, l, UseT (UnknownUse, u))) us + | IntersectionCases (ls, u) -> + List.mapi (fun i l -> (i, reason_of_use_t u, l, u)) ls + +and ignore_of_spec = function + | IntersectionCases (_, CallT (_, callt)) -> Some (callt.return_t) + | _ -> None + +and choices_of_spec = function + | UnionCases (_, ts) + | IntersectionCases (ts, _) + -> ts + +and fire_actions cx trace = List.iter (function + | _, Speculation.Action.Flow (l, u) -> rec_flow cx trace (l, u) + | _, Speculation.Action.Unify (t1, t2) -> rec_unify cx trace t1 t2 +) + +and mk_union_reason r us = + List.fold_left (fun reason t -> let rdesc = desc_of_reason reason in let tdesc = desc_of_reason (reason_of_t t) in let udesc = if not (Utils.str_starts_with rdesc "union:") @@ -4514,239 +5355,12 @@ and try_union cx trace l reason rep = else if Utils.str_ends_with rdesc tdesc then spf "%s(s)" rdesc else spf "%s | %s" rdesc tdesc - in - (* try head member, package the rest *) - let r = replace_reason udesc reason in - let next_attempt = UnionT (r, UnionRep.tail rep) in - (* TODO: pass in use_op? *) - let u = UseT (UnknownUse, next_attempt) in - rec_flow_t cx trace (SpeculativeMatchT(r, l, u), t) - | [] -> - (* fail *) - match UnionRep.(history rep, errors rep) with - | [], [] -> - (* shouldn't happen, but... if no history, give blanket error *) - rec_flow_t cx trace (l, UnionT (reason, UnionRep.empty)) - | ts, errs -> - (* otherwise, build extra info from history *) - let tslen, errslen = List.length ts, List.length errs in - let extra = if tslen <> errslen - then None (* temp fix to prevent List.combine error *) - else Some (List.(rev (combine ts errs)) |> List.mapi ( - fun i (t, err) -> - let header_infos = [ - Loc.none, [spf "Member %d:" (i + 1)]; - info_of_reason (reason_of_t t); - Loc.none, ["Error:"]; - ] in - let error_infos, error_extra = Errors.( - infos_of_error err, extra_of_error err - ) in - let info_list = header_infos @ error_infos in - let info_tree = match error_extra with - | [] -> Errors.InfoLeaf (info_list) - | _ -> Errors.InfoNode (info_list, error_extra) - in - info_tree - )) in - (* TODO: pass in use_op? *) - let u = UseT (UnknownUse, UnionT (reason, UnionRep.empty)) in - flow_err cx trace (err_msg l u) ?extra l u - -(** try the first member of an intersection, packaging the remainder - for subsequent attempts. Empty intersection indicates failure *) -and try_intersection cx trace u reason rep = - match InterRep.members rep with - | t :: _ -> - (* try the head member, package the rest *) - let r = replace_reason "intersection" reason in - let next_attempt = IntersectionT (r, InterRep.tail rep) in - rec_flow_t cx trace (t, SpeculativeMatchT (reason, next_attempt, u)) - | [] -> - (* fail *) - match InterRep.(history rep, errors rep) with - | [], [] -> - (* shouldn't happen, but... if no history, give blanket error *) - rec_flow cx trace (IntersectionT (reason, InterRep.empty), u) - | ts, errs -> - (* otherwise, build extra info from history *) - let tslen, errslen = List.length ts, List.length errs in - let extra = if tslen <> errslen - then None (* temp fix to prevent List.combine error *) - else Some (List.(rev (combine ts errs)) |> List.mapi ( - fun i (t, err) -> - let header_infos = [ - Loc.none, [spf "Member %d:" (i + 1)]; - info_of_reason (reason_of_t t); - Loc.none, ["Error:"]; - ] in - let error_infos, error_extra = Errors.( - infos_of_error err, extra_of_error err - ) in - let info_list = header_infos @ error_infos in - let info_tree = match error_extra with - | [] -> Errors.InfoLeaf (info_list) - | _ -> Errors.InfoNode (info_list, error_extra) - in - info_tree - )) in - let l = IntersectionT (reason, InterRep.empty) in - flow_err cx trace (err_msg l u) ?extra l u - -(* Some types need their parts to be concretized (i.e., type variables may need - to be replaced by concrete types) so that speculation has a chance to fail - early (and other branches are tried): otherwise, those failures may remain - latent, and cause spurious errors to be reported. *) - -(** TODO: switch to concretization for other types that need multiple parts - to be concretized, e.g. AdderT, ComparatorT, ObjAssignT... *) - -(** Upper and lower bounds have disjoint concretization processes, and we - look for different types to concretize in each case. But the processes - have the same general shape: - - 1. A particular rule needs an UB (resp. LB) to be fully concrete to - proceed, so it calls upper/lower_parts_to_concretize. If the type is fully - concrete already, an empty list is returned, otherwise the list contains - component types to be concretized. (The caller should treat this list as - an opaque value, apart from testing its emptiness.) - - 2. If the list from step 1 is non-empty, concretization is needed, and - the rule calls concretize_upper/lower_parts, passing the the (LB, UB) - pair along with the concretization list. This kicks off the concretization - process, which uses ConcretizeLower/UpperT to work through the list of - types without further intervention. - - (Note that concretization is not quite a simple recursive traversal of - the concretization list: when a tvar is exposed for concretization, the - edge from that tvar to the ConcretizeLower/UpperT holding the snapshot - of the corresponding concretization state persists in the graph: many - concrete LBs may flow through a tvar, and each induces a different - overall concretization.) - - 3. When the concretization process reaches the end of the todo list, - replace_upper/lower_concrete_types will build a fresh type using the - concretized parts, and feed the resulting LB/UB pair back into the flow - function. - - There's no fundamental need for the finished type to be structurally - similar to the original: in addition to concretizing, the final step - can do arbitrary transforms. - - But note the importance of guaranteeing termination: for the typechecker - not to loop[1], a type must eventually yield an empty concretization list - if passed repeatedly through this process. Every use-case so far will in - fact yield an empty list in one step, and there's no reason to think - that multiple steps will ever be needed. - - But care should be taken to avoid simply returning an incoming type as a - concretized result when there's nothing to do: instead these types should - return an empty concretization list (concretization is partial, not - idempotent). - - [1] The FlowConstraint cache will prevent the typechecker from actually - looping, but the circuit breaker will also prevent further typechecking - from taking place, making the error silent. To help trap this situation - we emit an explicit internal error when this equality is detected. - *) - -(** Concretize an upper bound. - - Currently we only need to concretize FunT and CallT UBs, to support - overloaded function selection. Here we'll request concretization - for any such type with tvars in its param list. - - Note: we expose the outflow tvars from AnnotT. There may be other - wrapper types that need similar treatment. - *) -and upper_parts_to_concretize _cx u = - let expose_tvars = List.map (function AnnotT (_, t) | t -> t) in - let has_tvar = List.exists (function OpenT _ -> true | _ -> false) in - match u with - | CallT (_, callt) (* call of overloaded function *) - | UseT (_, FunT (_, _, _, callt)) -> (* selection of overloaded function *) - let ts = expose_tvars callt.params_tlist in - if has_tvar ts then ts else [] - | _ -> [] - -and replace_upper_concrete_parts ts = function -| CallT (reason, callt) -> - CallT (reason, { callt with params_tlist = ts }) -| UseT (use_op, FunT (reason, static, prototype, callt)) -> - let callt = { callt with params_tlist = ts } in - UseT (use_op, FunT (reason, static, prototype, callt)) -| u -> u - -(** move a newly concretized type from the todo list (final param) to - the done list, and either continue concretizing or call flow on - the original LB and the fully concretized UB - *) -and concretize_upper_parts cx trace l u done_list = function -| [] -> - let done_list = List.rev done_list in - let concrete_u = replace_upper_concrete_parts done_list u in - - if u = concrete_u then flow_err cx trace - "Internal error: concretization leaves upper bound unchanged" l u; - - rec_flow cx trace (l, concrete_u) -| t :: todo_list -> - rec_flow cx trace (t, ConcretizeUpperT (l, todo_list, done_list, u)) - -(** Concretize a lower bound. - - Currently we concretize intersection LBs, so they can be manipulated - and checked in various ways. See replace_lower_concrete_parts. - *) -and lower_parts_to_concretize _cx = function -| IntersectionT (_, rep) -> - let ts = InterRep.members rep in - (** trap intersections that contain, or might contain, function types - which share a return type. - TODO: similarly we'll want to trap intersections that contain, - or might contain, incompatible object types. - Note also that we extract outflow tvars from AnnotT. - *) - let tvar, (* true if tvars present *) - fpart, (* funtypes partitioned by return value *) - ts = (* concretization list *) - List.fold_left (fun (tvar, fpart, acc) -> function - | AnnotT (_, t) | (OpenT _ as t) -> - true, fpart, t :: acc - | FunT _ as t -> tvar, Partition.add t fpart, t :: acc - | t -> tvar, fpart, t :: acc - ) (false, FunType.return_type_partition [], []) ts in - if tvar || not (Partition.is_discrete fpart) - then List.rev ts - else [] -| _ -> [] - -(** Note: here we may normalize or otherwise transform the result LB, - based on the concretized type list. - *) -and replace_lower_concrete_parts ts = function -| IntersectionT (r, _) -> ( - match FunType.merge_funtypes_by_return_type ts with - | [t] -> t - | ts -> IntersectionT (r, InterRep.make ts) -) -| l -> l - -(** move a newly concretized type from the todo list (final param) to - the done list, and either continue concretizing or call flow on - the fully concretized LB and the original UB - *) -and concretize_lower_parts cx trace l u done_list = function -| [] -> - let done_list = List.rev done_list in - let concrete_l = replace_lower_concrete_parts done_list l in - - if l = concrete_l then flow_err cx trace - "Internal error: concretization leaves lower bound unchanged" l u; + in + replace_reason udesc reason + ) r us - rec_flow cx trace (concrete_l, u) -| t :: todo_list -> - rec_flow cx trace (t, ConcretizeLowerT (l, todo_list, done_list, u)) +and mk_intersection_reason r _ls = + replace_reason "intersection" r (* property lookup functions in objects and instances *) @@ -5314,20 +5928,42 @@ and predicate cx trace t (l,p) = match (l,p) with assert_false (spf "Unexpected predicate %s" (string_of_predicate p)) and prop_exists_test cx trace key sense obj result = - match obj with - | ObjT (_, { props_tmap; _}) -> + prop_exists_test_generic key cx trace result obj sense obj + +and prop_exists_test_generic key cx trace result orig_obj sense = function + | ObjT (_, { props_tmap; _}) as obj -> begin match read_prop_opt cx props_tmap key with | Some t -> let filter = if sense then filter_exists else filter_not_exists in begin match filter t with | EmptyT _ -> () (* provably unreachable, so prune *) - | _ -> rec_flow_t cx trace (obj, result) + | _ -> rec_flow_t cx trace (orig_obj, result) end | None -> - rec_flow_t cx trace (obj, result) + (* TODO: possibly unsound to filter out orig_obj here, but if we don't, + case elimination based on prop existence checking doesn't work for + (disjoint unions of) intersections of objects, where the prop appears + in a different branch of the intersection. It is easy to avoid this + unsoundness with slightly more work, but will wait until a + refactoring of property lookup lands to revisit. Tracked by + #11301092. *) + if orig_obj = obj then rec_flow_t cx trace (orig_obj, result) end + | IntersectionT (_, rep) -> + (* For an intersection of object types, try the test for each object type in + turn, while recording the original intersection so that we end up with + the right refinement. See the comment on the implementation of + IntersectionPreprocessKit for more details. *) + let reason = reason_of_t result in + InterRep.members rep |> List.iter (fun obj -> + rec_flow cx trace ( + obj, + intersection_preprocess_kit reason + (PropExistsTest(sense, key, orig_obj, result)) + ) + ) | _ -> - rec_flow_t cx trace (obj, result) + rec_flow_t cx trace (orig_obj, result) and binary_predicate cx trace sense test left right result = let handler = @@ -5438,7 +6074,10 @@ and instanceof_test cx trace result = function | (false, left, _) -> rec_flow_t cx trace (left, result) -and sentinel_prop_test key cx trace result = function +and sentinel_prop_test key cx trace result (sense, obj, t) = + sentinel_prop_test_generic key cx trace result obj (sense, obj, t) + +and sentinel_prop_test_generic key cx trace result orig_obj = function (** Evaluate a refinement predicate of the form obj.key eq value @@ -5474,11 +6113,17 @@ and sentinel_prop_test key cx trace result = function (match read_prop_opt cx props_tmap key with | Some t -> let sentinel = SentinelStr value in - let test = SentinelPropTestT (obj, sense, sentinel, result) in + let test = SentinelPropTestT (orig_obj, sense, sentinel, result) in rec_flow cx trace (t, test) | None -> - (* property doesn't exist, unable to prune case *) - rec_flow_t cx trace (obj, result) + (* TODO: possibly unsound to filter out orig_obj here, but if we + don't, case elimination based on sentinel prop checking doesn't + work for (disjoint unions of) intersections of objects, where the + sentinel prop and the payload appear in different branches of the + intersection. It is easy to avoid this unsoundness with slightly + more work, but will wait until a refactoring of property lookup + lands to revisit. Tracked by #11301092. *) + if orig_obj = obj then rec_flow_t cx trace (orig_obj, result) ) (* obj.key ===/!== number value *) @@ -5486,11 +6131,17 @@ and sentinel_prop_test key cx trace result = function (match read_prop_opt cx props_tmap key with | Some t -> let sentinel = SentinelNum value in - let test = SentinelPropTestT (obj, sense, sentinel, result) in + let test = SentinelPropTestT (orig_obj, sense, sentinel, result) in rec_flow cx trace (t, test) | None -> - (* property doesn't exist, unable to prune case *) - rec_flow_t cx trace (obj, result) + (* TODO: possibly unsound to filter out orig_obj here, but if we + don't, case elimination based on sentinel prop checking doesn't + work for (disjoint unions of) intersections of objects, where the + sentinel prop and the payload appear in different branches of the + intersection. It is easy to avoid this unsoundness with slightly + more work, but will wait until a refactoring of property lookup + lands to revisit. Tracked by #11301092. *) + if orig_obj = obj then rec_flow_t cx trace (orig_obj, result) ) (* obj.key ===/!== boolean value *) @@ -5498,15 +6149,37 @@ and sentinel_prop_test key cx trace result = function (match read_prop_opt cx props_tmap key with | Some t -> let sentinel = SentinelBool value in - let test = SentinelPropTestT (obj, sense, sentinel, result) in + let test = SentinelPropTestT (orig_obj, sense, sentinel, result) in rec_flow cx trace (t, test) | None -> - (* property doesn't exist, unable to prune case *) - rec_flow_t cx trace (obj, result) + (* TODO: possibly unsound to filter out orig_obj here, but if we + don't, case elimination based on sentinel prop checking doesn't + work for (disjoint unions of) intersections of objects, where the + sentinel prop and the payload appear in different branches of the + intersection. It is easy to avoid this unsoundness with slightly + more work, but will wait until a refactoring of property lookup + lands to revisit. Tracked by #11301092. *) + if orig_obj = obj then rec_flow_t cx trace (orig_obj, result) ) - | (_, obj, _) -> (* not enough info to refine *) - rec_flow_t cx trace (obj, result) + | sense, IntersectionT (_, rep), + (StrT (_, Literal _) | NumT (_, Literal (_, _)) | BoolT (_, Some _) as t) + -> + (* For an intersection of object types, try the test for each object type in + turn, while recording the original intersection so that we end up with + the right refinement. See the comment on the implementation of + IntersectionPreprocessKit for more details. *) + let reason = reason_of_t result in + InterRep.members rep |> List.iter (fun obj -> + rec_flow cx trace ( + obj, + intersection_preprocess_kit reason + (SentinelPropTest(sense, key, t, orig_obj, result)) + ) + ) + + | _ -> (* not enough info to refine *) + rec_flow_t cx trace (orig_obj, result) (***********************) (* bounds manipulation *) @@ -5798,11 +6471,23 @@ and ok_unify = function and rec_unify cx trace t1 t2 = if t1 = t2 then () else ( - (* Expect that t1 and t2 are def types. *) + (* In general, unifying t1 and t2 should have similar effects as flowing t1 to + t2 and flowing t2 to t1. This also means that any restrictions on such + flows should also be enforced here. In particular, we don't expect t1 or t2 + to be type parameters, and we don't expect t1 or t2 to be def types that + don't make sense as use types. See __flow for more details. *) not_expect_bound t1; not_expect_bound t2; + expect_proper_def t1; expect_proper_def t2; + + (* Before processing the unify action, check that it is not deferred. If it + is, then when speculation is complete, the action either fires or is + discarded depending on whether the case that created the action is + selected or not. *) + if not (defer_action cx (Speculation.Action.Unify (t1, t2))) then match t1, t2 with + | OpenT (_, id1), OpenT (_, id2) -> merge_ids cx trace id1 id2 @@ -5984,7 +6669,7 @@ and multiflow_partial cx trace ?strict = function place that constrained the type arg. this is pretty hacky. *) let tout = let u = UseT (UnknownUse, tout) in - if ImplicitTypeArgument.has_typeparam_prefix (desc_of_t tin) + if has_typeparam_prefix (desc_of_t tin) then u else ReposLowerT (reason_of_t tin, u) in @@ -6071,10 +6756,10 @@ and mk_instance cx instance_reason ?(for_type=true) c = (* this part is similar to making a runtime value *) flow_opt_t cx (c, TypeT(instance_reason,t)) ) in - let sink_t = mk_tvar_where cx instance_reason (fun t -> - (* when source_t is concrete, unify with sink_t *) - flow_opt cx (source_t, UnifyT(source_t, t)) - ) in + (* TODO: Actually, sink_t is redundant now with ReposUseT, so we can remove + it. Basically ReposUseT takes care of capturing lower bounds and flowing + them to the resolved annotation when it is ready. *) + let sink_t = source_t in AnnotT (sink_t, source_t) else mk_tvar_derivable_where cx instance_reason (fun t -> @@ -6250,12 +6935,12 @@ and tvar_with_constraint cx u = flow cx (tvar, u) ) -(************* end of slab **************************************************) - (* Externally visible function for unification. *) -let unify cx t1 t2 = +and unify cx t1 t2 = rec_unify cx (Trace.unit_trace t1 (UseT (UnknownUse, t2))) t1 t2 +(************* end of slab **************************************************) + let intersect_members cx members = match members with | [] -> SMap.empty @@ -6468,10 +7153,10 @@ let rec assert_ground ?(infer=false) cx skip ids t = | ObjT (_, { props_tmap = id; proto_t; _ }) -> unify cx proto_t AnyT.t; - iter_props cx id (fun _ -> assert_ground ~infer:true cx skip ids) + iter_props cx id (fun _ -> recurse ~infer:true) | ArrT (_, t, ts) -> - recurse t; + recurse ~infer:true t; List.iter recurse ts | ClassT t @@ -6508,7 +7193,7 @@ let rec assert_ground ?(infer=false) cx skip ids t = List.iter recurse (InterRep.members rep) | UnionT (_, rep) -> - List.iter recurse (UnionRep.members rep) + List.iter (recurse ~infer:true) (UnionRep.members rep) | AnyWithLowerBoundT t | AnyWithUpperBoundT t -> @@ -6557,8 +7242,8 @@ let rec assert_ground ?(infer=false) cx skip ids t = | FunProtoCallT _ | AbstractT _ | EvalT _ - | SpeculativeMatchT _ | ExtendsT _ + | ChoiceKitT _ | CustomFunT _ -> () (* TODO *) diff --git a/src/typing/funType.ml b/src/typing/funType.ml deleted file mode 100644 index 880fd8845c7..00000000000 --- a/src/typing/funType.ml +++ /dev/null @@ -1,154 +0,0 @@ -(** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the "flow" directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - *) - -(** manipulation of function types *) -(** TODO move big chunks of Flow_js into here *) -(** TODO same thing with object types into an ObjType module *) - -open Utils_js -open Reason_js -open Type - -(** given a function, return an exemplar of its return type. - Top-level reason is pinned to an internal blank, other - reasons are left unmodified. - - We use this below to partition function lists on common return - types ("common" meaning immediately equal, not unifiable). - - Note: non-FunTs are returned as-is. Reason scrubbing ensures - that non-FunTs and return type exemplars are disjoint. - *) -let return_type_ex = - let blank_r = reason_of_string "function return type" in - function - | FunT (_, _, _, { return_t; _ }) -> - mod_reason_of_t (fun _ -> blank_r) return_t - | t -> t - -(** partition a list of FunTs by return type. - Note: we allow non-FunTs - they become singleton cells in - the partition. - *) -let return_type_partition = - List.fold_left - (fun p ft -> Partition.add ft p) - (Partition.empty return_type_ex) - -(** given a list of types, merge any FunTs that share an obviously - equal return type, leaving everything else alone. - - The motivation for this is our current modeling of function - overloads by intersection types: to preserve the correlation - between param signatures and return types in an overload list, - we avoid normalizing intersections of function types into a - single merged signature - but this means that bona fide function - intersections are mishandled. By merging only function types - whose return types are manifestly equal, we service the most - common use case while preserving the desired behavior for - overloading. - - TODO use a new OverloadT to model overload selection lists - (and maybe add surface syntax for it), and replace this - with a full normalization over intersections. - - Note: here merging function types means taking their intersection: - - taking the union of each param type in the shared arity - - setting param type to MixedT outside the shared arity - - in the general case, we would take the intersection of return - types, but here we explicitly confine the merge to functions - whose return types are equal. This is necessary while we - continue to model function overloading with IntersectionT. - - statics are currently set to MixedT. TODO - - proto is currently set to MixedT. TODO - - this is currently set to MixedT. TODO - - Selection order is preserved: a merged FunT will appear in - the position of its first constituent. Eg - - merge_funtypes_by_return_type - [(bool) => string; (number) => void; (Object) => bool; (string) => void] - > [(bool) => string; (number | string) => void; (Object) => bool] - - *) -let merge_funtypes_by_return_type = - - (* merge pair of FunTs *) - let merge_pair acc t = - match acc, t with - | FunT (reason_x, _static_x, _proto_x, { - this_t = _this_x; - params_tlist = params_x; params_names = names_x; - return_t = ret_x; closure_t = _closure_x; - changeset = _changeset_x }), - FunT (_reason_y, _static_y, _proto_y, { - this_t = _this_y; - params_tlist = params_y; params_names = names_y; - return_t = _ret_y; closure_t = _closure_y; - changeset = _changeset_y }) -> - - let arity_x, arity_y = List.(length params_x, length params_y) in - let shared_arity = min arity_x arity_y in - let extra_arity = (max arity_x arity_y) - shared_arity in - - let r = mk_reason "function intersection" (loc_of_reason reason_x) in - - FunT (r, - MixedT.t, (* statics TODO *) - MixedT.t, (* proto TODO *) - { - this_t = MixedT.t; (* TODO *) - - params_tlist = List.map2 (fun p1 p2 -> - match p1, p2 with - | UnionT (r, rep), _ -> - let ts = List.rev (p2 :: List.rev (UnionRep.members rep)) in - UnionT (r, UnionRep.make ts) - | _ -> - let r = reason_of_t p1 in - UnionT (r, UnionRep.make [p1; p2]) - ) (ListUtils.first_n shared_arity params_x) - (ListUtils.first_n shared_arity params_y) - - @ ListUtils.copy_n extra_arity MixedT.t; - - params_names = - if arity_x > arity_y then names_x else names_y; - - return_t = ret_x; - - closure_t = -1; - changeset = Changeset.empty - }) - | _ -> assert_false "non-funtypes sent to merge_pair" - - in fun ts -> - let p = return_type_partition ts in - if Partition.is_discrete p then ts else - (* for each type in ts, merge and/or transfer to result list *) - let ts, _ = List.fold_left (fun (ts, done_fts) -> function - (* already merged, skip *) - | FunT _ as t when TypeSet.mem t done_fts -> - ts, done_fts - (* previously-unmerged FunT: merge the cell, mark seen, add *) - | FunT _ as t -> ( - match Partition.cell t p with - | [] -> assert_false "funtype not found in intersection partition" - | [t] -> t :: ts, TypeSet.add t done_fts - | ft :: fts as cell -> - let merged = List.fold_left merge_pair ft fts in - merged :: ts, - List.fold_left (fun acc t -> TypeSet.add t acc) done_fts cell - ) - (* non-FunT *) - | t -> t :: ts, done_fts - ) ([], TypeSet.empty) ts - in - List.rev ts diff --git a/src/typing/graph_explorer.ml b/src/typing/graph_explorer.ml new file mode 100644 index 00000000000..2df478d2129 --- /dev/null +++ b/src/typing/graph_explorer.ml @@ -0,0 +1,198 @@ +(** + * Copyright (c) 2013-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the "flow" directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + *) + +open Utils_js + +(* Custom efficient graph data structure to track exploration of a graph, as + nodes and edges are dynamically discovered. + + The primary purpose of the data structure is to immediately detect any node + that is "fully explored", meaning that all nodes that are transitively + reachable from it have been explored. As long as some of the nodes that are + reachable from a node have not been explored yet, the node is not fully + explored. + + A key assumption about the graph is that every node has the following "0->1" + property: it transitions in one step from a state where it has been + discovered (the "0" state) to a step where it has been explored (the "1" + state), i.e., all of its immediate outgoing edges are added at once. + + Certain tvars in Flow have the "0->1" property in the following sense: they + transition from unresolved to resolved in one step. We can therefore use the + data structure here to efficiently manage full resolution for such tvars. + + NOTE: This data structure is not guaranteed to work as intended if we try to + resolve an already resolved tvar, or never resolve an unresolved + tvar. Roughly, a tvar can be considered to have the 0->1 property whenever it + is guaranteed to receive one and only one lower bound over its lifetime. +*) + +(* There are two kinds of nodes: unexplored and explored. Explored nodes have + dependencies to unexplored nodes. Unexplored nodes have reverse dependencies + to explored nodes. Note that we always maintain dependencies (and reverse + dependencies) in transitively closed form. *) + +type unexplored = { + mutable rev_deps: ISet.t; +} + +type explored = { + mutable deps: ISet.t; +} + +(* union type of unexplored and explored nodes; useful for aggregation. *) +type node = +| Unexplored of unexplored +| Explored of explored + +(* The graph maintains the two sets of nodes separately, with edges going across + in both directions. In other words, the graph is bipartite. + + For efficiency, we also maintain a third set of nodes, namely the nodes that + have been fully explored. + + Logically these sets are disjoint. As explained above, each node starts out + as unexplored, and becomes explored when a set of edges are introduced from + the node to other nodes. When an explored node has no more dependencies, it + is moved to the finished set. + + That said, we sometimes aggressively mark nodes as finished (e.g., once we + reduce signature context graphs after merging), without taking the time to + clear out those nodes from the other sets. This is fine because we always + check membership in the set of finished nodes before doing any work. +*) +type graph = { + mutable unexplored_nodes: unexplored IMap.t; + mutable explored_nodes: explored IMap.t; + mutable finished: ISet.t; +} + +let new_graph finished = { + unexplored_nodes = IMap.empty; + explored_nodes = IMap.empty; + finished; +} + +(* Merge finished from other_graph to graph. + + We don't care about merging explored_nodes and unexplored_nodes from + other_graph, since those were local to other_graph and should have been + cleared in any case to optimize space. On the other hand, we do care about + preserving the explored_nodes and unexplored_nodes in graph, since they may + still be in use. +*) +let union_finished other_graph graph = + { graph with finished = ISet.union other_graph.finished graph.finished } + +let find_unexplored id graph = + IMap.find_unsafe id graph.unexplored_nodes + +let find_explored id graph = + IMap.find_unsafe id graph.explored_nodes + +(* status of a node *) +type stat = +| Found of node +| Finished +| Not_found + +(* look up status of a node in a graph *) +let stat_graph id graph = + if ISet.mem id graph.finished then Finished else + match IMap.get id graph.unexplored_nodes with + | Some unexplored -> Found (Unexplored unexplored) + | None -> begin match IMap.get id graph.explored_nodes with + | Some explored -> Found (Explored explored) + | None -> Not_found + end + +let find_graph id graph = + match stat_graph id graph with + | Found node -> node + | _ -> failwith (spf "expected node %d to exist" id) + +let is_finished explored = + ISet.is_empty explored.deps + +let is_finished_node = function + | Unexplored _ -> false + | Explored explored -> is_finished explored + +let is_unexplored_node = function + | Unexplored _ -> true + | Explored _ -> false + +(* Adding edges from node id1 to nodes in ids2. We assume that id1 is + unexplored, whereas ids2 may be explored or unexplored (but not finished). *) +(** NOTE: This process has a lot of similarities with how constraints on usual + tvars are handled in the context graph. In the future, we might move this + processing back into that framework, by introducing new kinds of tvars on + which this processing can apply. **) +let edges graph (id1, ids2) = + let unexplored1 = find_unexplored id1 graph in + graph.unexplored_nodes <- IMap.remove id1 graph.unexplored_nodes; + let explored1 = { deps = ISet.empty } in + graph.explored_nodes <- IMap.add id1 explored1 graph.explored_nodes; + + let finished_ids = ref ISet.empty in + + let ids2 = List.fold_left (fun ids2 id2 -> + match find_graph id2 graph with + | Unexplored unexplored2 -> + explored1.deps <- ISet.add id2 explored1.deps; + unexplored1.rev_deps |> ISet.iter (fun id0 -> + let explored0 = find_explored id0 graph in + explored0.deps <- ISet.add id2 explored0.deps; + ); + + unexplored2.rev_deps <- ISet.add id1 unexplored2.rev_deps; + unexplored2.rev_deps <- + ISet.union unexplored1.rev_deps unexplored2.rev_deps; + + ids2 + + | Explored explored2 -> + ISet.union explored2.deps ids2 + + ) ISet.empty ids2 in + + let ids2 = ISet.remove id1 ids2 in + + explored1.deps <- ISet.union ids2 explored1.deps; + unexplored1.rev_deps |> ISet.iter (fun id0 -> + let explored0 = find_explored id0 graph in + explored0.deps <- ISet.union ids2 explored0.deps; + ); + + ids2 |> ISet.iter (fun id2 -> + let unexplored2 = find_unexplored id2 graph in + unexplored2.rev_deps <- ISet.add id1 unexplored2.rev_deps; + unexplored2.rev_deps <- + ISet.union unexplored1.rev_deps unexplored2.rev_deps; + ); + + explored1.deps <- ISet.remove id1 explored1.deps; + if is_finished explored1 + then finished_ids := ISet.add id1 !finished_ids; + unexplored1.rev_deps |> ISet.iter (fun id0 -> + let explored0 = find_explored id0 graph in + explored0.deps <- ISet.remove id1 explored0.deps; + if is_finished explored0 + then finished_ids := ISet.add id0 !finished_ids; + ); + unexplored1.rev_deps <- ISet.empty; + + graph.finished <- ISet.union !finished_ids graph.finished; + !finished_ids + +(* Add a node to the graph *) +let node graph id = + let unexplored = { rev_deps = ISet.empty } in + graph.unexplored_nodes <- IMap.add id unexplored graph.unexplored_nodes diff --git a/src/typing/merge_js.ml b/src/typing/merge_js.ml index f484016939f..cb124626c21 100644 --- a/src/typing/merge_js.ml +++ b/src/typing/merge_js.ml @@ -228,6 +228,10 @@ module ContextOptimizer = struct Context.set_graph cx quotient.reduced_graph; Context.set_property_maps cx quotient.reduced_property_maps; Context.set_envs cx quotient.reduced_envs; + Context.set_type_graph cx ( + Graph_explorer.new_graph + (IMap.fold (fun k _ -> ISet.add k) quotient.reduced_graph ISet.empty) + ); other_cxs |> List.iter (fun other_cx -> let other_m = context_module other_cx in Context.add_module cx other_m (export other_cx) diff --git a/src/typing/partition.ml b/src/typing/partition.ml deleted file mode 100644 index 18b38c6e7b1..00000000000 --- a/src/typing/partition.ml +++ /dev/null @@ -1,59 +0,0 @@ -(** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the "flow" directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - *) - -open Type - -(** Partitions on Type.t - Given a function f: 'a -> Type.t, we can partition a - collection of 'a along f: each cell in the partition - contains values x of type 'a which share a common f x. - This module provides a basic data structure and API - for creating, updating and querying these. - *) - -type 'a t = - ('a -> Type.t) * (* partition function *) - ('a list) TypeMap.t * (* map from Type.t to cells *) - bool (* true if partition is discrete *) - -(** empty partition along f *) -let empty f = f, TypeMap.empty, true - -(** return a partition's cell for a given x *) -let cell x (f, m, _) = - let k = f x in - match TypeMap.get k m with - | None -> [] - | Some ts -> ts - -(** true if x is a member of p *) -let mem x p = - List.find ((=) x) (cell x p) - -(** add x to the given partition. - Note: no duplicate checking is done. - *) -let add x (f, m, d) = - let k = f x in - let cell = match TypeMap.get k m with - | None -> [] - | Some ts -> ts in - f, - TypeMap.add k (x :: cell) m, (* add x to cell *) - d && cell = [] (* track discreteness *) - -(** true if every cell contains a single item *) -let is_discrete (_, _, d) = d - -(** convenience: build a partition from a list - Note: cell lists preserve original order. - *) -let from f lst = - List.fold_left (fun p x -> add x p) (empty f) (List.rev lst) diff --git a/src/typing/speculation.ml b/src/typing/speculation.ml new file mode 100644 index 00000000000..42469ff24a0 --- /dev/null +++ b/src/typing/speculation.ml @@ -0,0 +1,177 @@ +(** + * Copyright (c) 2013-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the "flow" directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + *) + +(* Various data structures and functions used to prepare for and execute + speculative matching. *) + +(* First up, a model for flow and unify actions that are deferred during + speculative matching (and possibly fired afterwards). *) +module Action = struct + + type t = + | Flow of Type.t * Type.use_t + | Unify of Type.t * Type.t + + (* Extract types involved in an action. Actually we're only interested in + tvars and filter the types further (see below); but for now we don't mind + the redundancy. *) + let types = Type.(function + | Flow ((AnyT _ | EmptyT _), _) + | Flow (_, UseT (_, (AnyT _ | MixedT _))) + -> [] + | Flow (t1, UseT (_, t2)) -> [t1; t2] + | Flow (t1, _) -> [t1] + | Unify (t1, t2) -> [t1; t2] + ) + + (* Decide when two actions are the same. We use reasonless compare for types + involved in the actions. *) + let rec eq = function + | Flow (t1, t2), Flow (t1_, t2_) -> + eq_t (t1, t1_) && eq_use_t (t2, t2_) + | Unify (t1, t2), Unify (t1_, t2_) -> + eq_t (t1, t1_) && eq_t (t2, t2_) + | _ -> false + + and eq_t (t, t_) = + Type.reasonless_compare t t_ = 0 + + and eq_use_t = function + | Type.UseT (_, t), Type.UseT (_, t_) -> eq_t (t, t_) + | _ -> false + + (* Action extended with a bit that determines whether the action is "benign." + Roughly, actions that don't cause serious side effects are considered + benign. See ignore, ignore_type, and defer_if_relevant below for + details. *) + type extended_t = bool * t + +end + +type unresolved = Type.TypeSet.t + +(* Next, a model for "cases." A case serves as the context for a speculative + match. In other words, while we're trying to execute a flow in speculation + mode, we use this data structure to record stuff. *) +module Case = struct + + (* A case carries a (local) index that identifies which type we're currently + considering among the members of a union or intersection type. This is used + only for error reporting. + + Other than that, a case carries the unresolved tvars encountered and the + actions deferred during a speculative match. These start out empty and grow + as the speculative match proceeds. At the end of the speculative match, + they are used to decide where the type under consideration should be + selected, or otherwise how the match state should be updated. See the + speculative_matches function in Flow_js. *) + type t = { + case_id: int; + mutable unresolved: unresolved; + mutable actions: Action.extended_t list; + } + + (* A case could be diff'd with a later case to determine whether it is "less + constrained," i.e., whether it's failure would also imply the failure of + the later case. This is approximated by diff'ing the set of unresolved + tvars that are involved in non-benign actions in the two cases. *) + let diff case1 case2 = + let { unresolved = ts1; actions = actions1; _ } = case1 in + let { actions = actions2; _ } = case2 in + (* collect those actions in actions1 that are not benign and don't appear in + actions2 *) + let diff_actions1 = + List.filter (fun (benign, action1) -> + not benign && + List.for_all (fun (_, action2) -> not (Action.eq (action1, action2))) + actions2 + ) actions1 in + (* collect those unresolved tvars in ts1 that are involved in actions in + diff_actions1 *) + let diff_ts1 = + List.fold_left (fun diff_ts1 (_, diff_action1) -> + List.fold_left (fun diff_ts1 t1 -> + if Type.TypeSet.mem t1 ts1 + then Type.TypeSet.add t1 diff_ts1 + else diff_ts1 + ) diff_ts1 (Action.types diff_action1) + ) Type.TypeSet.empty diff_actions1 in + (* return *) + Type.TypeSet.elements diff_ts1 + +end + +(* Functions used to initialize and add unresolved tvars during type resolution + of lower/upper bounds of union/intersection types, respectively *) + +let init_speculation cx speculation_id = + Context.set_all_unresolved cx + (IMap.add speculation_id Type.TypeSet.empty (Context.all_unresolved cx)) + +let add_unresolved_to_speculation cx speculation_id t = + let map = Context.all_unresolved cx in + let ts = IMap.find_unsafe speculation_id map in + Context.set_all_unresolved cx + (IMap.add speculation_id (Type.TypeSet.add t ts) map) + +(* Actions that involve some "ignored" unresolved tvars are considered + benign. Such tvars can be explicitly designated to be ignored. Also, tvars + that instantiate type parameters, this types, existentials, etc. are + ignored. *) +type ignore = Type.t option +let ignore_type ignore t = + match ignore with + | Some ignore_t when ignore_t = t -> true + | _ -> begin match t with + | Type.OpenT (r, _) -> Reason_js.is_instantiable_reason r + | _ -> false + end + +(* A branch is a wrapper around a case, that also carries the speculation id of + the spec currently being processed, as well as any explicitly designated + ignored tvar. *) +type branch = { + ignore: ignore; + speculation_id: int; + case: Case.t; +} + +(* Decide, for a flow or unify action encountered during a speculative match, + whether that action should be deferred. Only a relevant action is deferred. A + relevant action is not benign, and it must involve a tvar that was marked + unresolved during full type resolution of the lower/upper bound of the + union/intersection type being processed. + + As a side effect, whenever we decide to defer an action, we record the + deferred action and the unresolved tvars involved in it in the current case. +*) +let defer_if_relevant cx branch action = + let { ignore; speculation_id; case } = branch in + let action_types = Action.types action in + let all_unresolved = + IMap.find_unsafe speculation_id (Context.all_unresolved cx) in + let relevant_action_types = + List.filter (fun t -> Type.TypeSet.mem t all_unresolved) action_types in + let defer = relevant_action_types <> [] in + if defer then Case.( + let is_benign = List.exists (ignore_type ignore) action_types in + if not is_benign + then case.unresolved <- + List.fold_left (fun unresolved t -> Type.TypeSet.add t unresolved) + case.unresolved relevant_action_types; + case.actions <- case.actions @ [is_benign, action] + ); + defer + +(* The state maintained by speculative_matches when trying each case of a + union/intersection in turn. *) +type match_state = +| NoMatch of Errors_js.error list +| ConditionalMatch of Case.t diff --git a/src/typing/statement.ml b/src/typing/statement.ml index 2c778aa8392..14b80c2538d 100644 --- a/src/typing/statement.ml +++ b/src/typing/statement.ml @@ -2415,10 +2415,10 @@ and expression_ ~is_cond cx type_params_map loc e = Ast.Expression.(match e with | Array { Array.elements } -> ( let reason = mk_reason "array literal" loc in - let element_reason = mk_reason "array element" loc in match elements with | [] -> (* empty array, analogous to object with implicit properties *) + let element_reason = mk_reason "unknown element type of empty array" loc in let elemt = Flow.mk_tvar cx element_reason in ArrT (prefix_reason "empty " reason, elemt, []) | elems -> @@ -2435,10 +2435,42 @@ and expression_ ~is_cond cx type_params_map loc e = Ast.Expression.(match e with if tup then elemt :: tlist else [] ) (true, TypeExSet.empty, []) elems in - (* composite elem type is union *) + (* composite elem type is an upper bound of all element types *) let elemt = match TypeExSet.elements tset with | [t] -> t - | list -> UnionT (element_reason, UnionRep.make list) + | list -> + let element_reason = mk_reason "inferred union of array element types \ +(alternatively, provide an annotation to summarize the array element type)" + loc in + (* Should the element type of the array be the union of its element + types? + + No. Instead of using a union, we use an unresolved tvar to + represent the least upper bound of each element type. Effectively, + this keeps the element type "open," at least locally.[*] + + Using a union pins down the element type prematurely, and moreover, + might lead to speculative matching when setting elements or caling + contravariant methods (`push`, `concat`, etc.) on the array. + + In any case, using a union doesn't quite work as intended today + when the element types themselves could be unresolved tvars. For + example, the following code would work even with unions: + + declare var o: { x: number; } + var a = ["hey", o.x]; // no error, but is an error is o.x is replaced by 42 + declare var i: number; + a[i] = false; + + [*] Eventually, the element type does get pinned down to a union + when it is part of the module's exports. In the future we might + have to do that pinning more carefully, and using an unresolved + tvar instead of a union here doesn't conflict with those plans. + *) + Flow_js.mk_tvar_where cx element_reason (fun tvar -> + list |> List.iter (fun t -> + Flow_js.flow cx (t, UseT (UnknownUse, tvar))) + ) in ArrT (reason, elemt, List.rev tlist) ) @@ -2704,10 +2736,26 @@ and expression_ ~is_cond cx type_params_map loc e = Ast.Expression.(match e with Env.update_env cx reason env; (* TODO call loc_of_predicate on some pred? t1 is wrong but hopefully close *) - Flow.mk_tvar_where cx reason (fun t -> - Flow.flow_t cx (t1, t); - Flow.flow_t cx (t2, t); - ) + + (* NOTE: In general it is dangerous to express the least upper bound of + some types as a union: it might pin down the least upper bound + prematurely (before all the types have been inferred), and when the + union appears as an upper bound, it might lead to speculative matching. + + However, here a union is safe, because this union is guaranteed to only + appear as a lower bound. + + In such "covariant" positions, avoiding unnecessary indirection via + tvars is a good thing, because it improves precision. In particular, it + enables more types to be fully resolvable, which improves results of + speculative matching. + + It should be possible to do this more broadly and systematically. For + example, results of operations on annotations (like property gets on + objects, calls on functions) are often represented as unresolved tvars, + where they could be pinned down to resolved types. + *) + UnionT (reason, UnionRep.make [t1; t2]) | Assignment { Assignment.operator; left; right } -> assignment cx type_params_map loc (left, operator, right) @@ -3019,10 +3067,13 @@ and binary cx type_params_map loc = Ast.Expression.Binary.(function let t2 = expression cx type_params_map right in let reason1 = mk_reason "LHS of `in` operator" loc1 in let reason2 = mk_reason "RHS of `in` operator" loc2 in - let lhs = UnionT (reason1, UnionRep.make [StrT.why reason1; NumT.why reason1]) in + let lhs = + UnionT (reason1, UnionRep.make [StrT.why reason1; NumT.why reason1]) in let rhs = - let elemt = Flow.mk_tvar cx reason2 in - UnionT (reason2, UnionRep.make [AnyObjT reason2; ArrT (reason2, elemt, [])]) + UnionT (reason2, UnionRep.make [ + AnyObjT reason2; + ArrT (reason2, AnyT reason2, []) (* approximation of "any array" *) + ]) in Flow.flow_t cx (t1, lhs); Flow.flow_t cx (t2, rhs); diff --git a/src/typing/type.ml b/src/typing/type.ml index de64e586b4c..453041c6192 100644 --- a/src/typing/type.ml +++ b/src/typing/type.ml @@ -228,11 +228,12 @@ module rec TypeTerm : sig (** Here's to the crazy ones. The misfits. The rebels. The troublemakers. The round pegs in the square holes. **) - (* failure case for speculative matching *) - | SpeculativeMatchT of reason * t * use_t (* util for deciding subclassing relations *) | ExtendsT of t list * t * t + (* toolkit for making choices *) + | ChoiceKitT of reason * choice_tool + (* Sigil representing functions that the type system is not expressive enough to annotate, so we customize their behavior internally. *) | CustomFunT of reason * custom_fun_kind @@ -392,14 +393,13 @@ module rec TypeTerm : sig * into intersection bugs. *) | ReactCreateElementT of reason * t * t_out - | DebugPrintT of reason + (* toolkit for making choices, contd. (appearing only as upper bounds) *) + | ChoiceKitUseT of reason * choice_use_tool - (** Here's to the crazy ones. The misfits. The rebels. The troublemakers. The - round pegs in the square holes. **) + (* tools for preprocessing intersections *) + | IntersectionPreprocessKitT of reason * intersection_preprocess_tool - (* manage a worklist of types to be concretized *) - | ConcretizeLowerT of t * t list * t list * use_t - | ConcretizeUpperT of t * t list * t list * use_t + | DebugPrintT of reason | SentinelPropTestT of t * bool * sentinel_value * t_out @@ -571,6 +571,22 @@ module rec TypeTerm : sig | SentinelNum of number_literal | SentinelBool of bool + and choice_tool = + | Trigger + + and choice_use_tool = + | FullyResolveType of ident + | TryFlow of int * spec + + and intersection_preprocess_tool = + | ConcretizeTypes of t list * t list * t * use_t + | SentinelPropTest of bool * string * t * t * t + | PropExistsTest of bool * string * t * t + + and spec = + | UnionCases of t * t list + | IntersectionCases of t list * use_t + end = TypeTerm (* We encapsulate UnionT's internal structure @@ -929,6 +945,12 @@ let is_use = function | UseT _ -> false | _ -> true +(* not all so-called def types can appear as use types *) +(* TODO: separate these misfits out *) +let is_proper_def = function + | ChoiceKitT _ -> false + | _ -> true + (* convenience *) let is_bot = function | EmptyT _ -> true @@ -1040,10 +1062,10 @@ let rec reason_of_t = function | SingletonNumT (reason, _) | SingletonBoolT (reason, _) -> reason - | SpeculativeMatchT (reason, _, _) -> reason - | ModuleT (reason, _) -> reason + | ChoiceKitT (reason, _) -> reason + | CustomFunT (reason, _) -> reason | ExtendsT (_,_,t) -> @@ -1122,9 +1144,6 @@ and reason_of_use_t = function | ElemT (reason, _, _, _) -> reason - | ConcretizeLowerT (t, _, _, _) -> reason_of_t t - | ConcretizeUpperT (_, _, _, t) -> reason_of_use_t t - | SummarizeT (reason, _) -> reason | CJSRequireT (reason, _) -> reason @@ -1143,6 +1162,9 @@ and reason_of_use_t = function | SentinelPropTestT (_, _, _, result) -> reason_of_t result + | ChoiceKitUseT (reason, _) -> reason + | IntersectionPreprocessKitT (reason, _) -> reason + (* helper: we want the tvar id as well *) (* NOTE: uncalled for now, because ids are nondetermistic due to parallelism, which messes up test diffs. Should @@ -1257,13 +1279,12 @@ let rec mod_reason_of_t f = function | SingletonNumT (reason, t) -> SingletonNumT (f reason, t) | SingletonBoolT (reason, t) -> SingletonBoolT (f reason, t) - | SpeculativeMatchT (reason, t1, t2) -> - SpeculativeMatchT (f reason, t1, t2) - | ModuleT (reason, exports) -> ModuleT (f reason, exports) | ExtendsT (ts, t, tc) -> ExtendsT (ts, t, mod_reason_of_t f tc) + | ChoiceKitT (reason, tool) -> ChoiceKitT (f reason, tool) + | CustomFunT (reason, kind) -> CustomFunT (f reason, kind) and mod_reason_of_defer_use_t f = function @@ -1331,11 +1352,6 @@ and mod_reason_of_use_t f = function | ElemT (reason, t, t2, rw) -> ElemT (f reason, t, t2, rw) - | ConcretizeLowerT (t1, ts1, ts2, t2) -> - ConcretizeLowerT (mod_reason_of_t f t1, ts1, ts2, t2) - | ConcretizeUpperT (t1, ts1, ts2, t2) -> - ConcretizeUpperT (t1, ts1, ts2, mod_reason_of_use_t f t2) - | SummarizeT (reason, t) -> SummarizeT (f reason, t) | CJSRequireT (reason, t) -> CJSRequireT (f reason, t) @@ -1356,6 +1372,9 @@ and mod_reason_of_use_t f = function | SentinelPropTestT (l, sense, sentinel, result) -> SentinelPropTestT (l, sense, sentinel, mod_reason_of_t f result) + | ChoiceKitUseT (reason, tool) -> ChoiceKitUseT (f reason, tool) + | IntersectionPreprocessKitT (reason, tool) -> IntersectionPreprocessKitT (f reason, tool) + (* type comparison mod reason *) let reasonless_compare = let swap_reason t r = mod_reason_of_t (fun _ -> r) t in @@ -1423,7 +1442,6 @@ let string_of_ctor = function | TaintT _ -> "TaintT" | IntersectionT _ -> "IntersectionT" | UnionT _ -> "UnionT" - | SpeculativeMatchT _ -> "SpeculativeMatchT" | AnyWithLowerBoundT _ -> "AnyWithLowerBoundT" | AnyWithUpperBoundT _ -> "AnyWithUpperBoundT" | AnyObjT _ -> "AnyObjT" @@ -1436,6 +1454,10 @@ let string_of_ctor = function | SingletonBoolT _ -> "SingletonBoolT" | ModuleT _ -> "ModuleT" | ExtendsT _ -> "ExtendsT" + | ChoiceKitT (_, tool) -> + spf "ChoiceKitT %s" begin match tool with + | Trigger -> "Trigger" + end | CustomFunT _ -> "CustomFunT" let string_of_use_op = function @@ -1486,8 +1508,6 @@ let string_of_use_ctor = function | HasOwnPropT _ -> "HasOwnPropT" | HasPropT _ -> "HasPropT" | ElemT _ -> "ElemT" - | ConcretizeLowerT _ -> "ConcretizeLowerT" - | ConcretizeUpperT _ -> "ConcretizeUpperT" | ImportModuleNsT _ -> "ImportModuleNsT" | ImportDefaultT _ -> "ImportDefaultT" | ImportNamedT _ -> "ImportNamedT" @@ -1502,6 +1522,17 @@ let string_of_use_ctor = function | TupleMapT _ -> "TupleMapT" | ReactCreateElementT _ -> "ReactCreateElementT" | SentinelPropTestT _ -> "SentinelPropTestT" + | ChoiceKitUseT (_, tool) -> + spf "ChoiceKitUseT %s" begin match tool with + | FullyResolveType _ -> "FullyResolveType" + | TryFlow _ -> "TryFlow" + end + | IntersectionPreprocessKitT (_, tool) -> + spf "IntersectionPreprocessKitT %s" begin match tool with + | ConcretizeTypes _ -> "ConcretizeTypes" + | SentinelPropTest _ -> "SentinelPropTest" + | PropExistsTest _ -> "PropExistsTest" + end let string_of_binary_test = function | InstanceofTest -> "instanceof" diff --git a/src/typing/type_annotation.ml b/src/typing/type_annotation.ml index f3790137e9a..2482bc25354 100644 --- a/src/typing/type_annotation.ml +++ b/src/typing/type_annotation.ml @@ -93,9 +93,25 @@ let rec convert cx type_params_map = Ast.Type.(function let reason = mk_reason "tuple type" loc in let element_reason = mk_reason "tuple element" loc in let tx = - if ts = [] - then Flow_js.mk_tvar cx element_reason - else UnionT (element_reason, UnionRep.make elts) in + if ts = [] then Flow_js.mk_tvar cx element_reason + else + (* If a tuple should be viewed as an array, what would the element type of + the array be? + + Using a union here seems appealing but is wrong: setting elements + through arbitrary indices at the union type would be unsound, since it + might violate the projected types of the tuple at their corresponding + positions. This also shows why `mixed` doesn't work, either. + + On the other hand, using the empty type would prevent writes, but admit + unsound reads. + + The correct solution is to safely case a tuple type to a covariant + array interface whose element type would be a union. Until we have + that, we use the following closest approximation, that behaves like a + union as a lower bound but `any` as an upper bound. + *) + AnyWithLowerBoundT (UnionT (element_reason, UnionRep.make elts)) in ArrT (reason, tx, elts) | loc, Array t -> @@ -242,7 +258,7 @@ let rec convert cx type_params_map = Ast.Type.(function environment. Currently, we only support this types in a class environment: a this type in class C is bounded by C. *) check_type_param_arity cx loc typeParameters 0 (fun () -> - let reason = mk_reason "`this` type" loc in + let reason = mk_reason thistype_desc loc in Flow_js.reposition cx reason (SMap.find_unsafe "this" type_params_map) ) else ( @@ -470,7 +486,7 @@ let rec convert cx type_params_map = Ast.Type.(function ensures that existential type variables under a polymorphic type remain unevaluated until the polymorphic type is applied. *) let force = SMap.is_empty type_params_map in - let reason = derivable_reason (mk_reason "existential" loc) in + let reason = derivable_reason (mk_reason existential_desc loc) in if force then Flow_js.mk_tvar cx reason else ExistsT reason ) diff --git a/src/typing/type_normalizer.ml b/src/typing/type_normalizer.ml index def810728cc..d29d4f72bda 100644 --- a/src/typing/type_normalizer.ml +++ b/src/typing/type_normalizer.ml @@ -101,6 +101,9 @@ let rec normalize_type_impl cx ids t = match t with let params_names = Some ["thisArg"; "argArray"] in fake_fun params_names tins any + | ChoiceKitT (_, _) -> + AnyT.t + (* Fake the signature of $Facebookism$Merge: *) (* (...objects: Array): Object *) | CustomFunT (_, Merge) -> @@ -326,7 +329,6 @@ let rec normalize_type_impl cx ids t = match t with | FunProtoT _ | ExistsT _ | ModuleT (_, _) - | SpeculativeMatchT (_, _, _) | ExtendsT (_, _, _) -> (** TODO **) failwith (spf "Unsupported type in normalize_type_impl: %s" (string_of_ctor t)) diff --git a/src/typing/type_printer.ml b/src/typing/type_printer.ml index 970b0484534..998956b6baf 100644 --- a/src/typing/type_printer.ml +++ b/src/typing/type_printer.ml @@ -280,12 +280,11 @@ let rec is_printed_type_parsable_impl weak cx enclosure = function -> true - | ArrT (_, t, _ts) + | ArrT (_, t, ts) -> - (*(match ts with - | [] -> *)is_printed_type_parsable_impl weak cx EnclosureNone t - (*| _ -> - is_printed_type_list_parsable weak cx EnclosureNone t*) + (match ts with + | [] -> is_printed_type_parsable_impl weak cx EnclosureNone t + | ts -> is_printed_type_list_parsable weak cx EnclosureNone ts) | RestT t when (enclosure == EnclosureParam) diff --git a/src/typing/type_visitor.ml b/src/typing/type_visitor.ml index aee574c661f..8f4ef0d0fcd 100644 --- a/src/typing/type_visitor.ml +++ b/src/typing/type_visitor.ml @@ -22,6 +22,8 @@ class ['a] t = object(self) method type_ cx (acc: 'a) = function | OpenT (r, id) -> self#tvar cx acc r id + | ChoiceKitT (_, Trigger) -> acc + | NumT _ | StrT _ | BoolT _ @@ -131,11 +133,6 @@ class ['a] t = object(self) let acc = self#type_ cx acc t2 in acc - | SpeculativeMatchT (_, t1, t2) -> - let acc = self#type_ cx acc t1 in - let acc = self#use_type_ cx acc t2 in - acc - | ModuleT (_, exporttypes) -> self#export_types cx acc exporttypes @@ -194,8 +191,6 @@ class ['a] t = object(self) | ArrRestT (_, _, _) | UnaryMinusT (_, _) | UnifyT (_, _) - | ConcretizeLowerT (_, _, _, _) - | ConcretizeUpperT (_, _, _, _) | GetKeysT (_, _) | HasOwnPropT (_, _) | HasPropT (_, _, _) @@ -214,6 +209,8 @@ class ['a] t = object(self) | TupleMapT (_, _, _) | ReactCreateElementT _ | SentinelPropTestT _ + | ChoiceKitUseT (_, _) + | IntersectionPreprocessKitT (_, _) -> self#__TODO__ cx acc (* The default behavior here could be fleshed out a bit, to look up the graph, diff --git a/tests/arraylib/arraylib.exp b/tests/arraylib/arraylib.exp index b6d3419fcbe..cd790ad81ba 100644 --- a/tests/arraylib/arraylib.exp +++ b/tests/arraylib/arraylib.exp @@ -35,103 +35,48 @@ array_lib.js:21 ^^^^^^^^^^^^^^^^^^^^^^^ call of method `concat` 21: var n: Array = h.concat('a', 'b', 'c'); // Error ^^^ string. This type is incompatible with -union: array type | type parameter `S` of call of method `concat`. See lib: core.js:182 - Member 1: - array type. See lib: core.js:182 - Error: - 21: var n: Array = h.concat('a', 'b', 'c'); // Error - ^^^ string. This type is incompatible with - array type. See lib: core.js:182 - Member 2: - 21: var n: Array = h.concat('a', 'b', 'c'); // Error - ^^^^^^^^^^^^^^^^^^^^^^^ type parameter `S` of call of method `concat` - Error: - 21: var n: Array = h.concat('a', 'b', 'c'); // Error - ^^^ string. This type is incompatible with - 21: var n: Array = h.concat('a', 'b', 'c'); // Error - ^^^^^^ number + 21: var n: Array = h.concat('a', 'b', 'c'); // Error + ^^^^^^ number array_lib.js:21 21: var n: Array = h.concat('a', 'b', 'c'); // Error ^^^^^^^^^^^^^^^^^^^^^^^ call of method `concat` 21: var n: Array = h.concat('a', 'b', 'c'); // Error ^^^ string. This type is incompatible with -union: array type | type parameter `S` of call of method `concat`. See lib: core.js:182 - Member 1: - array type. See lib: core.js:182 - Error: - 21: var n: Array = h.concat('a', 'b', 'c'); // Error - ^^^ string. This type is incompatible with - array type. See lib: core.js:182 - Member 2: - 21: var n: Array = h.concat('a', 'b', 'c'); // Error - ^^^^^^^^^^^^^^^^^^^^^^^ type parameter `S` of call of method `concat` - Error: - 21: var n: Array = h.concat('a', 'b', 'c'); // Error - ^^^ string. This type is incompatible with - 21: var n: Array = h.concat('a', 'b', 'c'); // Error - ^^^^^^ number + 21: var n: Array = h.concat('a', 'b', 'c'); // Error + ^^^^^^ number array_lib.js:21 21: var n: Array = h.concat('a', 'b', 'c'); // Error ^^^^^^^^^^^^^^^^^^^^^^^ call of method `concat` 21: var n: Array = h.concat('a', 'b', 'c'); // Error ^^^ string. This type is incompatible with -union: array type | type parameter `S` of call of method `concat`. See lib: core.js:182 - Member 1: - array type. See lib: core.js:182 - Error: - 21: var n: Array = h.concat('a', 'b', 'c'); // Error - ^^^ string. This type is incompatible with - array type. See lib: core.js:182 - Member 2: - 21: var n: Array = h.concat('a', 'b', 'c'); // Error - ^^^^^^^^^^^^^^^^^^^^^^^ type parameter `S` of call of method `concat` - Error: - 21: var n: Array = h.concat('a', 'b', 'c'); // Error - ^^^ string. This type is incompatible with - 21: var n: Array = h.concat('a', 'b', 'c'); // Error - ^^^^^^ number + 21: var n: Array = h.concat('a', 'b', 'c'); // Error + ^^^^^^ number array_lib.js:46 46: [""].reduce((acc, str) => acc * str.length); // error, string ~> number - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call of method `reduce`. Function cannot be called on any member of intersection type + ^^^ string. This type is incompatible with + 46: [""].reduce((acc, str) => acc * str.length); // error, string ~> number + ^^^^^^^^^^^^^^^^ number + +array_lib.js:46 46: [""].reduce((acc, str) => acc * str.length); // error, string ~> number - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ intersection - Member 1: - polymorphic type: function type. See lib: core.js:199 - Error: - 46: [""].reduce((acc, str) => acc * str.length); // error, string ~> number - ^^^ undefined (too few arguments, expected default/rest parameters). This type is incompatible with - 46: [""].reduce((acc, str) => acc * str.length); // error, string ~> number - ^^^^^^^^^^^^^^^^ number - Member 2: - polymorphic type: function type. See lib: core.js:203 - Error: - 46: [""].reduce((acc, str) => acc * str.length); // error, string ~> number - ^^^ string. This type is incompatible with - 46: [""].reduce((acc, str) => acc * str.length); // error, string ~> number - ^^^^^^^^^^^^^^^^ number + ^^^^^^^^^^^^^^^^ number. This type is incompatible with + 46: [""].reduce((acc, str) => acc * str.length); // error, string ~> number + ^^ string + +array_lib.js:47 + 47: [""].reduceRight((acc, str) => acc * str.length); // error, string ~> number + ^^^ string. This type is incompatible with + 47: [""].reduceRight((acc, str) => acc * str.length); // error, string ~> number + ^^^^^^^^^^^^^^^^ number array_lib.js:47 47: [""].reduceRight((acc, str) => acc * str.length); // error, string ~> number - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call of method `reduceRight`. Function cannot be called on any member of intersection type + ^^^^^^^^^^^^^^^^ number. This type is incompatible with 47: [""].reduceRight((acc, str) => acc * str.length); // error, string ~> number - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ intersection - Member 1: - polymorphic type: function type. See lib: core.js:206 - Error: - 47: [""].reduceRight((acc, str) => acc * str.length); // error, string ~> number - ^^^ undefined (too few arguments, expected default/rest parameters). This type is incompatible with - 47: [""].reduceRight((acc, str) => acc * str.length); // error, string ~> number - ^^^^^^^^^^^^^^^^ number - Member 2: - polymorphic type: function type. See lib: core.js:210 - Error: - 47: [""].reduceRight((acc, str) => acc * str.length); // error, string ~> number - ^^^ string. This type is incompatible with - 47: [""].reduceRight((acc, str) => acc * str.length); // error, string ~> number - ^^^^^^^^^^^^^^^^ number + ^^ string -Found 9 errors +Found 11 errors diff --git a/tests/arrows/arrows.exp b/tests/arrows/arrows.exp index 6f1c9fdf977..a7e1a85253d 100644 --- a/tests/arrows/arrows.exp +++ b/tests/arrows/arrows.exp @@ -15,7 +15,7 @@ arrows.js:7 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call of method `sort` 7: images = images.sort((a, b) => (a.width - b.width) + ""); ^^^^^^^^^^^^^^^^^^^^^^^^ string. This type is incompatible with -number. See lib: core.js:217 +number. See lib: core.js:219 Found 3 errors diff --git a/tests/async/async.exp b/tests/async/async.exp index f4f10169941..397abeb318a 100644 --- a/tests/async/async.exp +++ b/tests/async/async.exp @@ -1,40 +1,14 @@ async.js:12 12: return 1; // error, number != bool ^ number. This type is incompatible with -union: type application of identifier `Promise` | type parameter `T` of async return. See lib: core.js:492 - Member 1: - type application of identifier `Promise`. See lib: core.js:492 - Error: - 12: return 1; // error, number != bool - ^ number. This type is incompatible with - Promise. See lib: core.js:492 - Member 2: - 12: return 1; // error, number != bool - ^^^^^^^^^ type parameter `T` of async return - Error: - 12: return 1; // error, number != bool - ^ number. This type is incompatible with - 11: async function f1(): Promise { - ^^^^ boolean + 11: async function f1(): Promise { + ^^^^ boolean async.js:31 31: return await p; // error, number != bool ^^^^^^^ number. This type is incompatible with -union: type application of identifier `Promise` | type parameter `T` of async return. See lib: core.js:492 - Member 1: - type application of identifier `Promise`. See lib: core.js:492 - Error: - 31: return await p; // error, number != bool - ^^^^^^^ number. This type is incompatible with - Promise. See lib: core.js:492 - Member 2: - 31: return await p; // error, number != bool - ^^^^^^^^^^^^^^^ type parameter `T` of async return - Error: - 31: return await p; // error, number != bool - ^^^^^^^ number. This type is incompatible with - 30: async function f4(p: Promise): Promise { - ^^^^ boolean + 30: async function f4(p: Promise): Promise { + ^^^^ boolean async.js:45 45: static async m(a): void { await a; } // error, void != Promise diff --git a/tests/autocomplete/autocomplete.exp b/tests/autocomplete/autocomplete.exp index 7c3b10315bb..087ef5870c7 100644 --- a/tests/autocomplete/autocomplete.exp +++ b/tests/autocomplete/autocomplete.exp @@ -8,7 +8,7 @@ valueOf () => Object foo.js = {"result":[{"name":"hasOwnProperty","type":"(prop: any) => boolean","func_details":{"return_type":"boolean","params":[{"name":"prop","type":"any"}]},"path":"[LIB] core.js","line":52,"endline":52,"start":5,"end":38},{"name":"num","type":"number","func_details":null,"path":"foo.js","line":6,"endline":6,"start":8,"end":10},{"name":"propertyIsEnumerable","type":"(prop: any) => boolean","func_details":{"return_type":"boolean","params":[{"name":"prop","type":"any"}]},"path":"[LIB] core.js","line":53,"endline":53,"start":5,"end":44},{"name":"str","type":"string","func_details":null,"path":"foo.js","line":7,"endline":7,"start":8,"end":14},{"name":"toLocaleString","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":54,"endline":54,"start":5,"end":28},{"name":"toString","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":55,"endline":55,"start":5,"end":22},{"name":"valueOf","type":"() => Object","func_details":{"return_type":"Object","params":[]},"path":"[LIB] core.js","line":56,"endline":56,"start":5,"end":21}]} bar.js = {"error":"not enough type information to autocomplete","result":[]} qux.js = {"result":[{"name":"x","type":"number","func_details":null,"path":"qux.js","line":3,"endline":3,"start":14,"end":19}]} -str.js = {"result":[{"name":"@@iterator","type":"() => Iterator","func_details":{"return_type":"Iterator","params":[]},"path":"[LIB] core.js","line":234,"endline":234,"start":5,"end":34},{"name":"anchor","type":"(name: string) => string","func_details":{"return_type":"string","params":[{"name":"name","type":"string"}]},"path":"[LIB] core.js","line":235,"endline":235,"start":5,"end":32},{"name":"charAt","type":"(pos: number) => string","func_details":{"return_type":"string","params":[{"name":"pos","type":"number"}]},"path":"[LIB] core.js","line":236,"endline":236,"start":5,"end":31},{"name":"charCodeAt","type":"(index: number) => number","func_details":{"return_type":"number","params":[{"name":"index","type":"number"}]},"path":"[LIB] core.js","line":237,"endline":237,"start":5,"end":37},{"name":"codePointAt","type":"(index: number) => number","func_details":{"return_type":"number","params":[{"name":"index","type":"number"}]},"path":"[LIB] core.js","line":238,"endline":238,"start":5,"end":38},{"name":"concat","type":"(...strings: Array) => string","func_details":{"return_type":"string","params":[{"name":"...strings","type":"Array"}]},"path":"[LIB] core.js","line":239,"endline":239,"start":5,"end":45},{"name":"endsWith","type":"(searchString: string, position?: number) => boolean","func_details":{"return_type":"boolean","params":[{"name":"searchString","type":"string"},{"name":"position?","type":"number"}]},"path":"[LIB] core.js","line":240,"endline":240,"start":5,"end":62},{"name":"includes","type":"(searchString: string, position?: number) => boolean","func_details":{"return_type":"boolean","params":[{"name":"searchString","type":"string"},{"name":"position?","type":"number"}]},"path":"[LIB] core.js","line":241,"endline":241,"start":5,"end":62},{"name":"indexOf","type":"(searchString: string, position?: number) => number","func_details":{"return_type":"number","params":[{"name":"searchString","type":"string"},{"name":"position?","type":"number"}]},"path":"[LIB] core.js","line":242,"endline":242,"start":5,"end":60},{"name":"lastIndexOf","type":"(searchString: string, position?: number) => number","func_details":{"return_type":"number","params":[{"name":"searchString","type":"string"},{"name":"position?","type":"number"}]},"path":"[LIB] core.js","line":243,"endline":243,"start":5,"end":64},{"name":"length","type":"number","func_details":null,"path":"[LIB] core.js","line":264,"endline":264,"start":13,"end":18},{"name":"link","type":"(href: string) => string","func_details":{"return_type":"string","params":[{"name":"href","type":"string"}]},"path":"[LIB] core.js","line":244,"endline":244,"start":5,"end":30},{"name":"localeCompare","type":"(that: string) => number","func_details":{"return_type":"number","params":[{"name":"that","type":"string"}]},"path":"[LIB] core.js","line":245,"endline":245,"start":5,"end":39},{"name":"match","type":"(regexp: string | RegExp) => ?Array","func_details":{"return_type":"?Array","params":[{"name":"regexp","type":"string | RegExp"}]},"path":"[LIB] core.js","line":246,"endline":246,"start":5,"end":50},{"name":"normalize","type":"(format?: string) => string","func_details":{"return_type":"string","params":[{"name":"format?","type":"string"}]},"path":"[LIB] core.js","line":247,"endline":247,"start":5,"end":38},{"name":"repeat","type":"(count: number) => string","func_details":{"return_type":"string","params":[{"name":"count","type":"number"}]},"path":"[LIB] core.js","line":248,"endline":248,"start":5,"end":33},{"name":"replace","type":"(searchValue: string | RegExp, replaceValue: string | ((substring: string, ...args: Array) => string)) => string","func_details":{"return_type":"string","params":[{"name":"searchValue","type":"string | RegExp"},{"name":"replaceValue","type":"string | ((substring: string, ...args: Array) => string)"}]},"path":"[LIB] core.js","line":249,"endline":249,"start":5,"end":124},{"name":"search","type":"(regexp: string | RegExp) => number","func_details":{"return_type":"number","params":[{"name":"regexp","type":"string | RegExp"}]},"path":"[LIB] core.js","line":250,"endline":250,"start":5,"end":43},{"name":"slice","type":"(start?: number, end?: number) => string","func_details":{"return_type":"string","params":[{"name":"start?","type":"number"},{"name":"end?","type":"number"}]},"path":"[LIB] core.js","line":251,"endline":251,"start":5,"end":47},{"name":"split","type":"(separator: string | RegExp, limit?: number) => Array","func_details":{"return_type":"Array","params":[{"name":"separator","type":"string | RegExp"},{"name":"limit?","type":"number"}]},"path":"[LIB] core.js","line":252,"endline":252,"start":5,"end":68},{"name":"startsWith","type":"(searchString: string, position?: number) => boolean","func_details":{"return_type":"boolean","params":[{"name":"searchString","type":"string"},{"name":"position?","type":"number"}]},"path":"[LIB] core.js","line":253,"endline":253,"start":5,"end":64},{"name":"substr","type":"(from: number, length?: number) => string","func_details":{"return_type":"string","params":[{"name":"from","type":"number"},{"name":"length?","type":"number"}]},"path":"[LIB] core.js","line":254,"endline":254,"start":5,"end":49},{"name":"substring","type":"(start: number, end?: number) => string","func_details":{"return_type":"string","params":[{"name":"start","type":"number"},{"name":"end?","type":"number"}]},"path":"[LIB] core.js","line":255,"endline":255,"start":5,"end":50},{"name":"toLocaleLowerCase","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":256,"endline":256,"start":5,"end":31},{"name":"toLocaleUpperCase","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":257,"endline":257,"start":5,"end":31},{"name":"toLowerCase","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":258,"endline":258,"start":5,"end":25},{"name":"toUpperCase","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":259,"endline":259,"start":5,"end":25},{"name":"trim","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":260,"endline":260,"start":5,"end":18},{"name":"trimLeft","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":261,"endline":261,"start":5,"end":22},{"name":"trimRight","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":262,"endline":262,"start":5,"end":23},{"name":"valueOf","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":263,"endline":263,"start":5,"end":21}]} +str.js = {"result":[{"name":"@@iterator","type":"() => Iterator","func_details":{"return_type":"Iterator","params":[]},"path":"[LIB] core.js","line":236,"endline":236,"start":5,"end":34},{"name":"anchor","type":"(name: string) => string","func_details":{"return_type":"string","params":[{"name":"name","type":"string"}]},"path":"[LIB] core.js","line":237,"endline":237,"start":5,"end":32},{"name":"charAt","type":"(pos: number) => string","func_details":{"return_type":"string","params":[{"name":"pos","type":"number"}]},"path":"[LIB] core.js","line":238,"endline":238,"start":5,"end":31},{"name":"charCodeAt","type":"(index: number) => number","func_details":{"return_type":"number","params":[{"name":"index","type":"number"}]},"path":"[LIB] core.js","line":239,"endline":239,"start":5,"end":37},{"name":"codePointAt","type":"(index: number) => number","func_details":{"return_type":"number","params":[{"name":"index","type":"number"}]},"path":"[LIB] core.js","line":240,"endline":240,"start":5,"end":38},{"name":"concat","type":"(...strings: Array) => string","func_details":{"return_type":"string","params":[{"name":"...strings","type":"Array"}]},"path":"[LIB] core.js","line":241,"endline":241,"start":5,"end":45},{"name":"endsWith","type":"(searchString: string, position?: number) => boolean","func_details":{"return_type":"boolean","params":[{"name":"searchString","type":"string"},{"name":"position?","type":"number"}]},"path":"[LIB] core.js","line":242,"endline":242,"start":5,"end":62},{"name":"includes","type":"(searchString: string, position?: number) => boolean","func_details":{"return_type":"boolean","params":[{"name":"searchString","type":"string"},{"name":"position?","type":"number"}]},"path":"[LIB] core.js","line":243,"endline":243,"start":5,"end":62},{"name":"indexOf","type":"(searchString: string, position?: number) => number","func_details":{"return_type":"number","params":[{"name":"searchString","type":"string"},{"name":"position?","type":"number"}]},"path":"[LIB] core.js","line":244,"endline":244,"start":5,"end":60},{"name":"lastIndexOf","type":"(searchString: string, position?: number) => number","func_details":{"return_type":"number","params":[{"name":"searchString","type":"string"},{"name":"position?","type":"number"}]},"path":"[LIB] core.js","line":245,"endline":245,"start":5,"end":64},{"name":"length","type":"number","func_details":null,"path":"[LIB] core.js","line":266,"endline":266,"start":13,"end":18},{"name":"link","type":"(href: string) => string","func_details":{"return_type":"string","params":[{"name":"href","type":"string"}]},"path":"[LIB] core.js","line":246,"endline":246,"start":5,"end":30},{"name":"localeCompare","type":"(that: string) => number","func_details":{"return_type":"number","params":[{"name":"that","type":"string"}]},"path":"[LIB] core.js","line":247,"endline":247,"start":5,"end":39},{"name":"match","type":"(regexp: string | RegExp) => ?Array","func_details":{"return_type":"?Array","params":[{"name":"regexp","type":"string | RegExp"}]},"path":"[LIB] core.js","line":248,"endline":248,"start":5,"end":50},{"name":"normalize","type":"(format?: string) => string","func_details":{"return_type":"string","params":[{"name":"format?","type":"string"}]},"path":"[LIB] core.js","line":249,"endline":249,"start":5,"end":38},{"name":"repeat","type":"(count: number) => string","func_details":{"return_type":"string","params":[{"name":"count","type":"number"}]},"path":"[LIB] core.js","line":250,"endline":250,"start":5,"end":33},{"name":"replace","type":"(searchValue: string | RegExp, replaceValue: string | ((substring: string, ...args: Array) => string)) => string","func_details":{"return_type":"string","params":[{"name":"searchValue","type":"string | RegExp"},{"name":"replaceValue","type":"string | ((substring: string, ...args: Array) => string)"}]},"path":"[LIB] core.js","line":251,"endline":251,"start":5,"end":124},{"name":"search","type":"(regexp: string | RegExp) => number","func_details":{"return_type":"number","params":[{"name":"regexp","type":"string | RegExp"}]},"path":"[LIB] core.js","line":252,"endline":252,"start":5,"end":43},{"name":"slice","type":"(start?: number, end?: number) => string","func_details":{"return_type":"string","params":[{"name":"start?","type":"number"},{"name":"end?","type":"number"}]},"path":"[LIB] core.js","line":253,"endline":253,"start":5,"end":47},{"name":"split","type":"(separator: string | RegExp, limit?: number) => Array","func_details":{"return_type":"Array","params":[{"name":"separator","type":"string | RegExp"},{"name":"limit?","type":"number"}]},"path":"[LIB] core.js","line":254,"endline":254,"start":5,"end":68},{"name":"startsWith","type":"(searchString: string, position?: number) => boolean","func_details":{"return_type":"boolean","params":[{"name":"searchString","type":"string"},{"name":"position?","type":"number"}]},"path":"[LIB] core.js","line":255,"endline":255,"start":5,"end":64},{"name":"substr","type":"(from: number, length?: number) => string","func_details":{"return_type":"string","params":[{"name":"from","type":"number"},{"name":"length?","type":"number"}]},"path":"[LIB] core.js","line":256,"endline":256,"start":5,"end":49},{"name":"substring","type":"(start: number, end?: number) => string","func_details":{"return_type":"string","params":[{"name":"start","type":"number"},{"name":"end?","type":"number"}]},"path":"[LIB] core.js","line":257,"endline":257,"start":5,"end":50},{"name":"toLocaleLowerCase","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":258,"endline":258,"start":5,"end":31},{"name":"toLocaleUpperCase","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":259,"endline":259,"start":5,"end":31},{"name":"toLowerCase","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":260,"endline":260,"start":5,"end":25},{"name":"toUpperCase","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":261,"endline":261,"start":5,"end":25},{"name":"trim","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":262,"endline":262,"start":5,"end":18},{"name":"trimLeft","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":263,"endline":263,"start":5,"end":22},{"name":"trimRight","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":264,"endline":264,"start":5,"end":23},{"name":"valueOf","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":265,"endline":265,"start":5,"end":21}]} num.js = {"result":[{"name":"toExponential","type":"(fractionDigits?: number) => string","func_details":{"return_type":"string","params":[{"name":"fractionDigits?","type":"number"}]},"path":"[LIB] core.js","line":125,"endline":125,"start":5,"end":50},{"name":"toFixed","type":"(fractionDigits?: number) => string","func_details":{"return_type":"string","params":[{"name":"fractionDigits?","type":"number"}]},"path":"[LIB] core.js","line":126,"endline":126,"start":5,"end":44},{"name":"toPrecision","type":"(precision?: number) => string","func_details":{"return_type":"string","params":[{"name":"precision?","type":"number"}]},"path":"[LIB] core.js","line":127,"endline":127,"start":5,"end":43},{"name":"toString","type":"(radix?: number) => string","func_details":{"return_type":"string","params":[{"name":"radix?","type":"number"}]},"path":"[LIB] core.js","line":128,"endline":128,"start":5,"end":36},{"name":"valueOf","type":"() => number","func_details":{"return_type":"number","params":[]},"path":"[LIB] core.js","line":129,"endline":129,"start":5,"end":21}]} bool.js = {"result":[{"name":"valueOf","type":"() => boolean","func_details":{"return_type":"boolean","params":[]},"path":"[LIB] core.js","line":106,"endline":106,"start":5,"end":22}]} union.js = {"result":[{"name":"bar","type":"string","func_details":null,"path":"union.js","line":3,"endline":3,"start":36,"end":41},{"name":"hasOwnProperty","type":"(prop: any) => boolean","func_details":{"return_type":"boolean","params":[{"name":"prop","type":"any"}]},"path":"[LIB] core.js","line":52,"endline":52,"start":5,"end":38},{"name":"propertyIsEnumerable","type":"(prop: any) => boolean","func_details":{"return_type":"boolean","params":[{"name":"prop","type":"any"}]},"path":"[LIB] core.js","line":53,"endline":53,"start":5,"end":44},{"name":"toLocaleString","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":54,"endline":54,"start":5,"end":28},{"name":"toString","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":55,"endline":55,"start":5,"end":22},{"name":"valueOf","type":"() => Object","func_details":{"return_type":"Object","params":[]},"path":"[LIB] core.js","line":56,"endline":56,"start":5,"end":21}]} @@ -23,4 +23,4 @@ jsx1.js = {"result":[{"name":"hasOwnProperty","type":"(prop: any) => boolean","f jsx2.js = {"result":[{"name":"hasOwnProperty","type":"(prop: any) => boolean","func_details":{"return_type":"boolean","params":[{"name":"prop","type":"any"}]},"path":"[LIB] core.js","line":52,"endline":52,"start":5,"end":38},{"name":"propertyIsEnumerable","type":"(prop: any) => boolean","func_details":{"return_type":"boolean","params":[{"name":"prop","type":"any"}]},"path":"[LIB] core.js","line":53,"endline":53,"start":5,"end":44},{"name":"toLocaleString","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":54,"endline":54,"start":5,"end":28},{"name":"toString","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":55,"endline":55,"start":5,"end":22},{"name":"valueOf","type":"() => Object","func_details":{"return_type":"Object","params":[]},"path":"[LIB] core.js","line":56,"endline":56,"start":5,"end":21},{"name":"x","type":"number","func_details":null,"path":"jsx2.js","line":6,"endline":6,"start":15,"end":20},{"name":"y","type":"string","func_details":null,"path":"jsx2.js","line":6,"endline":6,"start":26,"end":31}]} customfun.js = {"result":[{"name":"promiseAll","type":"(promises: Array) => Promise","func_details":{"return_type":"Promise","params":[{"name":"promises","type":"Array"}]},"path":"customfun.js","line":9,"endline":9,"start":1,"end":35},{"name":"objectGetPrototypeOf","type":"(o: any) => any","func_details":{"return_type":"any","params":[{"name":"o","type":"any"}]},"path":"customfun.js","line":7,"endline":7,"start":1,"end":55},{"name":"objectAssign","type":"(target: any, ...sources: Array) => any","func_details":{"return_type":"any","params":[{"name":"target","type":"any"},{"name":"...sources","type":"Array"}]},"path":"customfun.js","line":8,"endline":8,"start":1,"end":39},{"name":"mixin","type":"(...objects: Array) => [class: Object]","func_details":{"return_type":"[class: Object]","params":[{"name":"...objects","type":"Array"}]},"path":"customfun.js","line":6,"endline":6,"start":1,"end":38},{"name":"mergeInto","type":"(target: Object, ...objects: Array) => void","func_details":{"return_type":"void","params":[{"name":"target","type":"Object"},{"name":"...objects","type":"Array"}]},"path":"customfun.js","line":5,"endline":5,"start":1,"end":46},{"name":"mergeDeepInto","type":"(target: Object, ...objects: Array) => void","func_details":{"return_type":"void","params":[{"name":"target","type":"Object"},{"name":"...objects","type":"Array"}]},"path":"customfun.js","line":4,"endline":4,"start":1,"end":54},{"name":"merge","type":"(...objects: Array) => Object","func_details":{"return_type":"Object","params":[{"name":"...objects","type":"Array"}]},"path":"customfun.js","line":3,"endline":3,"start":1,"end":38},{"name":"exports","type":"{}","func_details":null,"path":"","line":0,"endline":0,"start":1,"end":0}]} issue-1368.js = {"result":[{"name":"extended","type":"string","func_details":null,"path":"issue-1368.js","line":11,"endline":11,"start":13,"end":18},{"name":"method","type":"() => void","func_details":{"return_type":"void","params":[]},"path":"issue-1368.js","line":18,"endline":21,"start":3,"end":3},{"name":"prop","type":"number","func_details":null,"path":"issue-1368.js","line":3,"endline":3,"start":9,"end":14}]} -if.js = {"result":[{"name":"@@iterator","type":"() => Iterator","func_details":{"return_type":"Iterator","params":[]},"path":"[LIB] core.js","line":234,"endline":234,"start":5,"end":34},{"name":"anchor","type":"(name: string) => string","func_details":{"return_type":"string","params":[{"name":"name","type":"string"}]},"path":"[LIB] core.js","line":235,"endline":235,"start":5,"end":32},{"name":"charAt","type":"(pos: number) => string","func_details":{"return_type":"string","params":[{"name":"pos","type":"number"}]},"path":"[LIB] core.js","line":236,"endline":236,"start":5,"end":31},{"name":"charCodeAt","type":"(index: number) => number","func_details":{"return_type":"number","params":[{"name":"index","type":"number"}]},"path":"[LIB] core.js","line":237,"endline":237,"start":5,"end":37},{"name":"codePointAt","type":"(index: number) => number","func_details":{"return_type":"number","params":[{"name":"index","type":"number"}]},"path":"[LIB] core.js","line":238,"endline":238,"start":5,"end":38},{"name":"concat","type":"(...strings: Array) => string","func_details":{"return_type":"string","params":[{"name":"...strings","type":"Array"}]},"path":"[LIB] core.js","line":239,"endline":239,"start":5,"end":45},{"name":"endsWith","type":"(searchString: string, position?: number) => boolean","func_details":{"return_type":"boolean","params":[{"name":"searchString","type":"string"},{"name":"position?","type":"number"}]},"path":"[LIB] core.js","line":240,"endline":240,"start":5,"end":62},{"name":"includes","type":"(searchString: string, position?: number) => boolean","func_details":{"return_type":"boolean","params":[{"name":"searchString","type":"string"},{"name":"position?","type":"number"}]},"path":"[LIB] core.js","line":241,"endline":241,"start":5,"end":62},{"name":"indexOf","type":"(searchString: string, position?: number) => number","func_details":{"return_type":"number","params":[{"name":"searchString","type":"string"},{"name":"position?","type":"number"}]},"path":"[LIB] core.js","line":242,"endline":242,"start":5,"end":60},{"name":"lastIndexOf","type":"(searchString: string, position?: number) => number","func_details":{"return_type":"number","params":[{"name":"searchString","type":"string"},{"name":"position?","type":"number"}]},"path":"[LIB] core.js","line":243,"endline":243,"start":5,"end":64},{"name":"length","type":"number","func_details":null,"path":"[LIB] core.js","line":264,"endline":264,"start":13,"end":18},{"name":"link","type":"(href: string) => string","func_details":{"return_type":"string","params":[{"name":"href","type":"string"}]},"path":"[LIB] core.js","line":244,"endline":244,"start":5,"end":30},{"name":"localeCompare","type":"(that: string) => number","func_details":{"return_type":"number","params":[{"name":"that","type":"string"}]},"path":"[LIB] core.js","line":245,"endline":245,"start":5,"end":39},{"name":"match","type":"(regexp: string | RegExp) => ?Array","func_details":{"return_type":"?Array","params":[{"name":"regexp","type":"string | RegExp"}]},"path":"[LIB] core.js","line":246,"endline":246,"start":5,"end":50},{"name":"normalize","type":"(format?: string) => string","func_details":{"return_type":"string","params":[{"name":"format?","type":"string"}]},"path":"[LIB] core.js","line":247,"endline":247,"start":5,"end":38},{"name":"repeat","type":"(count: number) => string","func_details":{"return_type":"string","params":[{"name":"count","type":"number"}]},"path":"[LIB] core.js","line":248,"endline":248,"start":5,"end":33},{"name":"replace","type":"(searchValue: string | RegExp, replaceValue: string | ((substring: string, ...args: Array) => string)) => string","func_details":{"return_type":"string","params":[{"name":"searchValue","type":"string | RegExp"},{"name":"replaceValue","type":"string | ((substring: string, ...args: Array) => string)"}]},"path":"[LIB] core.js","line":249,"endline":249,"start":5,"end":124},{"name":"search","type":"(regexp: string | RegExp) => number","func_details":{"return_type":"number","params":[{"name":"regexp","type":"string | RegExp"}]},"path":"[LIB] core.js","line":250,"endline":250,"start":5,"end":43},{"name":"slice","type":"(start?: number, end?: number) => string","func_details":{"return_type":"string","params":[{"name":"start?","type":"number"},{"name":"end?","type":"number"}]},"path":"[LIB] core.js","line":251,"endline":251,"start":5,"end":47},{"name":"split","type":"(separator: string | RegExp, limit?: number) => Array","func_details":{"return_type":"Array","params":[{"name":"separator","type":"string | RegExp"},{"name":"limit?","type":"number"}]},"path":"[LIB] core.js","line":252,"endline":252,"start":5,"end":68},{"name":"startsWith","type":"(searchString: string, position?: number) => boolean","func_details":{"return_type":"boolean","params":[{"name":"searchString","type":"string"},{"name":"position?","type":"number"}]},"path":"[LIB] core.js","line":253,"endline":253,"start":5,"end":64},{"name":"substr","type":"(from: number, length?: number) => string","func_details":{"return_type":"string","params":[{"name":"from","type":"number"},{"name":"length?","type":"number"}]},"path":"[LIB] core.js","line":254,"endline":254,"start":5,"end":49},{"name":"substring","type":"(start: number, end?: number) => string","func_details":{"return_type":"string","params":[{"name":"start","type":"number"},{"name":"end?","type":"number"}]},"path":"[LIB] core.js","line":255,"endline":255,"start":5,"end":50},{"name":"toLocaleLowerCase","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":256,"endline":256,"start":5,"end":31},{"name":"toLocaleUpperCase","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":257,"endline":257,"start":5,"end":31},{"name":"toLowerCase","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":258,"endline":258,"start":5,"end":25},{"name":"toUpperCase","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":259,"endline":259,"start":5,"end":25},{"name":"trim","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":260,"endline":260,"start":5,"end":18},{"name":"trimLeft","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":261,"endline":261,"start":5,"end":22},{"name":"trimRight","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":262,"endline":262,"start":5,"end":23},{"name":"valueOf","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":263,"endline":263,"start":5,"end":21}]} +if.js = {"result":[{"name":"@@iterator","type":"() => Iterator","func_details":{"return_type":"Iterator","params":[]},"path":"[LIB] core.js","line":236,"endline":236,"start":5,"end":34},{"name":"anchor","type":"(name: string) => string","func_details":{"return_type":"string","params":[{"name":"name","type":"string"}]},"path":"[LIB] core.js","line":237,"endline":237,"start":5,"end":32},{"name":"charAt","type":"(pos: number) => string","func_details":{"return_type":"string","params":[{"name":"pos","type":"number"}]},"path":"[LIB] core.js","line":238,"endline":238,"start":5,"end":31},{"name":"charCodeAt","type":"(index: number) => number","func_details":{"return_type":"number","params":[{"name":"index","type":"number"}]},"path":"[LIB] core.js","line":239,"endline":239,"start":5,"end":37},{"name":"codePointAt","type":"(index: number) => number","func_details":{"return_type":"number","params":[{"name":"index","type":"number"}]},"path":"[LIB] core.js","line":240,"endline":240,"start":5,"end":38},{"name":"concat","type":"(...strings: Array) => string","func_details":{"return_type":"string","params":[{"name":"...strings","type":"Array"}]},"path":"[LIB] core.js","line":241,"endline":241,"start":5,"end":45},{"name":"endsWith","type":"(searchString: string, position?: number) => boolean","func_details":{"return_type":"boolean","params":[{"name":"searchString","type":"string"},{"name":"position?","type":"number"}]},"path":"[LIB] core.js","line":242,"endline":242,"start":5,"end":62},{"name":"includes","type":"(searchString: string, position?: number) => boolean","func_details":{"return_type":"boolean","params":[{"name":"searchString","type":"string"},{"name":"position?","type":"number"}]},"path":"[LIB] core.js","line":243,"endline":243,"start":5,"end":62},{"name":"indexOf","type":"(searchString: string, position?: number) => number","func_details":{"return_type":"number","params":[{"name":"searchString","type":"string"},{"name":"position?","type":"number"}]},"path":"[LIB] core.js","line":244,"endline":244,"start":5,"end":60},{"name":"lastIndexOf","type":"(searchString: string, position?: number) => number","func_details":{"return_type":"number","params":[{"name":"searchString","type":"string"},{"name":"position?","type":"number"}]},"path":"[LIB] core.js","line":245,"endline":245,"start":5,"end":64},{"name":"length","type":"number","func_details":null,"path":"[LIB] core.js","line":266,"endline":266,"start":13,"end":18},{"name":"link","type":"(href: string) => string","func_details":{"return_type":"string","params":[{"name":"href","type":"string"}]},"path":"[LIB] core.js","line":246,"endline":246,"start":5,"end":30},{"name":"localeCompare","type":"(that: string) => number","func_details":{"return_type":"number","params":[{"name":"that","type":"string"}]},"path":"[LIB] core.js","line":247,"endline":247,"start":5,"end":39},{"name":"match","type":"(regexp: string | RegExp) => ?Array","func_details":{"return_type":"?Array","params":[{"name":"regexp","type":"string | RegExp"}]},"path":"[LIB] core.js","line":248,"endline":248,"start":5,"end":50},{"name":"normalize","type":"(format?: string) => string","func_details":{"return_type":"string","params":[{"name":"format?","type":"string"}]},"path":"[LIB] core.js","line":249,"endline":249,"start":5,"end":38},{"name":"repeat","type":"(count: number) => string","func_details":{"return_type":"string","params":[{"name":"count","type":"number"}]},"path":"[LIB] core.js","line":250,"endline":250,"start":5,"end":33},{"name":"replace","type":"(searchValue: string | RegExp, replaceValue: string | ((substring: string, ...args: Array) => string)) => string","func_details":{"return_type":"string","params":[{"name":"searchValue","type":"string | RegExp"},{"name":"replaceValue","type":"string | ((substring: string, ...args: Array) => string)"}]},"path":"[LIB] core.js","line":251,"endline":251,"start":5,"end":124},{"name":"search","type":"(regexp: string | RegExp) => number","func_details":{"return_type":"number","params":[{"name":"regexp","type":"string | RegExp"}]},"path":"[LIB] core.js","line":252,"endline":252,"start":5,"end":43},{"name":"slice","type":"(start?: number, end?: number) => string","func_details":{"return_type":"string","params":[{"name":"start?","type":"number"},{"name":"end?","type":"number"}]},"path":"[LIB] core.js","line":253,"endline":253,"start":5,"end":47},{"name":"split","type":"(separator: string | RegExp, limit?: number) => Array","func_details":{"return_type":"Array","params":[{"name":"separator","type":"string | RegExp"},{"name":"limit?","type":"number"}]},"path":"[LIB] core.js","line":254,"endline":254,"start":5,"end":68},{"name":"startsWith","type":"(searchString: string, position?: number) => boolean","func_details":{"return_type":"boolean","params":[{"name":"searchString","type":"string"},{"name":"position?","type":"number"}]},"path":"[LIB] core.js","line":255,"endline":255,"start":5,"end":64},{"name":"substr","type":"(from: number, length?: number) => string","func_details":{"return_type":"string","params":[{"name":"from","type":"number"},{"name":"length?","type":"number"}]},"path":"[LIB] core.js","line":256,"endline":256,"start":5,"end":49},{"name":"substring","type":"(start: number, end?: number) => string","func_details":{"return_type":"string","params":[{"name":"start","type":"number"},{"name":"end?","type":"number"}]},"path":"[LIB] core.js","line":257,"endline":257,"start":5,"end":50},{"name":"toLocaleLowerCase","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":258,"endline":258,"start":5,"end":31},{"name":"toLocaleUpperCase","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":259,"endline":259,"start":5,"end":31},{"name":"toLowerCase","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":260,"endline":260,"start":5,"end":25},{"name":"toUpperCase","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":261,"endline":261,"start":5,"end":25},{"name":"trim","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":262,"endline":262,"start":5,"end":18},{"name":"trimLeft","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":263,"endline":263,"start":5,"end":22},{"name":"trimRight","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":264,"endline":264,"start":5,"end":23},{"name":"valueOf","type":"() => string","func_details":{"return_type":"string","params":[]},"path":"[LIB] core.js","line":265,"endline":265,"start":5,"end":21}]} diff --git a/tests/call_properties/call_properties.exp b/tests/call_properties/call_properties.exp index d6cd1f8b400..02ad3b1f001 100644 --- a/tests/call_properties/call_properties.exp +++ b/tests/call_properties/call_properties.exp @@ -88,9 +88,25 @@ D.js:11 D.js:20 20: function e(x: { (): string; (x: number): string }): () => number { - ^^^^^^ string. This type is incompatible with the expected return type of + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ intersection. This type is incompatible with 20: function e(x: { (): string; (x: number): string }): () => number { - ^^^^^^ number + ^^^^^^^^^^^^ function type + Member 1: + 20: function e(x: { (): string; (x: number): string }): () => number { + ^^^^^^^^^^ function type + Error: + 20: function e(x: { (): string; (x: number): string }): () => number { + ^^^^^^ string. This type is incompatible with the expected return type of + 20: function e(x: { (): string; (x: number): string }): () => number { + ^^^^^^ number + Member 2: + 20: function e(x: { (): string; (x: number): string }): () => number { + ^^^^^^^^^^^^^^^^^^^ function type + Error: + 20: function e(x: { (): string; (x: number): string }): () => number { + ^^^^^^^^^^^^ undefined (too few arguments, expected default/rest parameters). This type is incompatible with + 20: function e(x: { (): string; (x: number): string }): () => number { + ^^^^^^ number E.js:2 2: var a : { someProp: number } = function () {}; diff --git a/tests/core_tests/core_tests.exp b/tests/core_tests/core_tests.exp index aec6221cec1..a610f933bf7 100644 --- a/tests/core_tests/core_tests.exp +++ b/tests/core_tests/core_tests.exp @@ -1,32 +1,48 @@ map.js:23 23: let x = new Map(['foo', 123]); // error - ^^^^^^^^^^^^^^^^^^^^^ constructor call. Function cannot be called on any member of intersection type + ^^^^^^^^^^^^^^^^^^^^^ constructor call 23: let x = new Map(['foo', 123]); // error - ^^^^^^^^^^^^^^^^^^^^^ intersection - Member 1: - polymorphic type: function type. See lib: core.js:424 - Error: - 23: let x = new Map(['foo', 123]); // error - ^^^^^^^^^^^^ array literal. This type is incompatible with - undefined. See lib: core.js:424 - Member 2: - polymorphic type: function type. See lib: core.js:425 - Error: - 23: let x = new Map(['foo', 123]); // error - ^^^^^^^^^^^^ array literal. This type is incompatible with - null. See lib: core.js:425 - Member 3: - polymorphic type: function type. See lib: core.js:426 - Error: - 23: let x = new Map(['foo', 123]); // error - ^^^ number. This type is incompatible with - tuple type. See lib: core.js:426 - Member 4: - polymorphic type: function type. See lib: core.js:427 - Error: - 23: let x = new Map(['foo', 123]); // error - ^^^ number. This type is incompatible with - tuple type. See lib: core.js:427 + ^^^^^ string. This type is incompatible with +tuple type. See lib: core.js:426 + +map.js:23 + 23: let x = new Map(['foo', 123]); // error + ^^^^^^^^^^^^^^^^^^^^^ constructor call + 23: let x = new Map(['foo', 123]); // error + ^^^ number. This type is incompatible with +tuple type. See lib: core.js:426 + +map.js:24 + 24: let y: Map = new Map([['foo', 123]]); // error + ^^^^^^^^^^^^^^^^^^^^^^^ constructor call + 24: let y: Map = new Map([['foo', 123]]); // error + ^^^^^^ number. This type is incompatible with + 24: let y: Map = new Map([['foo', 123]]); // error + ^^^^^ string + +map.js:24 + 24: let y: Map = new Map([['foo', 123]]); // error + ^^^^^^^^^^^^^^^^^^^^^^^ constructor call + 24: let y: Map = new Map([['foo', 123]]); // error + ^^^^^^ string. This type is incompatible with + 24: let y: Map = new Map([['foo', 123]]); // error + ^^^ number + +map.js:24 + 24: let y: Map = new Map([['foo', 123]]); // error + ^^^^^^^^^^^^^^^^^^^^^^^ constructor call + 24: let y: Map = new Map([['foo', 123]]); // error + ^^^^^ string. This type is incompatible with + 24: let y: Map = new Map([['foo', 123]]); // error + ^^^^^^ number + +map.js:24 + 24: let y: Map = new Map([['foo', 123]]); // error + ^^^^^^^^^^^^^^^^^^^^^^^ constructor call + 24: let y: Map = new Map([['foo', 123]]); // error + ^^^ number. This type is incompatible with + 24: let y: Map = new Map([['foo', 123]]); // error + ^^^^^^ string map.js:29 29: (x.get('foo'): boolean); // error, string | void @@ -41,7 +57,7 @@ map.js:29 ^^^^^^^^^^^^ call of method `get` 29: (x.get('foo'): boolean); // error, string | void ^^^^^^^ boolean. This type is incompatible with -undefined. See lib: core.js:432 +undefined. See lib: core.js:431 map.js:30 30: x.get(123); // error, wrong key type @@ -56,62 +72,42 @@ regexp.js:26 ^^^^^^^^^^^^^^^^^^ function call 26: RegExp('foo', 'z'); // error ^^^ string. This type is incompatible with -string enum. See lib: core.js:280 +string enum. See lib: core.js:282 regexp.js:27 27: new RegExp('foo', 'z'); // error ^^^^^^^^^^^^^^^^^^^^^^ constructor call 27: new RegExp('foo', 'z'); // error ^^^ string. This type is incompatible with -string enum. See lib: core.js:282 +string enum. See lib: core.js:284 weakset.js:19 19: let ws3 = new WeakSet([1, 2, 3]); // error, must be objects - ^^^^^^^^^^^^^^^^^^^^^^ constructor call. Function cannot be called on any member of intersection type + ^^^^^^^^^^^^^^^^^^^^^^ constructor call 19: let ws3 = new WeakSet([1, 2, 3]); // error, must be objects - ^^^^^^^^^^^^^^^^^^^^^^ intersection - Member 1: - polymorphic type: function type. See lib: core.js:465 - Error: - 19: let ws3 = new WeakSet([1, 2, 3]); // error, must be objects - ^^^^^^^^^ array literal. This type is incompatible with - undefined. See lib: core.js:465 - Member 2: - polymorphic type: function type. See lib: core.js:466 - Error: - 19: let ws3 = new WeakSet([1, 2, 3]); // error, must be objects - ^ number. This type is incompatible with - object type. See lib: core.js:466 - Member 3: - polymorphic type: function type. See lib: core.js:467 - Error: - 19: let ws3 = new WeakSet([1, 2, 3]); // error, must be objects - ^ number. This type is incompatible with - object type. See lib: core.js:467 + ^ number. This type is incompatible with +object type. See lib: core.js:463 + +weakset.js:19 + 19: let ws3 = new WeakSet([1, 2, 3]); // error, must be objects + ^^^^^^^^^^^^^^^^^^^^^^ constructor call + 19: let ws3 = new WeakSet([1, 2, 3]); // error, must be objects + ^ number. This type is incompatible with +object type. See lib: core.js:463 + +weakset.js:19 + 19: let ws3 = new WeakSet([1, 2, 3]); // error, must be objects + ^^^^^^^^^^^^^^^^^^^^^^ constructor call + 19: let ws3 = new WeakSet([1, 2, 3]); // error, must be objects + ^ number. This type is incompatible with +object type. See lib: core.js:463 weakset.js:36 36: let ws5 = new WeakSet(numbers()); // error, must be objects - ^^^^^^^^^^^^^^^^^^^^^^ constructor call. Function cannot be called on any member of intersection type - 36: let ws5 = new WeakSet(numbers()); // error, must be objects - ^^^^^^^^^^^^^^^^^^^^^^ intersection - Member 1: - polymorphic type: function type. See lib: core.js:465 - Error: - 36: let ws5 = new WeakSet(numbers()); // error, must be objects - ^^^^^^^^^ $Iterable. This type is incompatible with - undefined. See lib: core.js:465 - Member 2: - polymorphic type: function type. See lib: core.js:466 - Error: - 36: let ws5 = new WeakSet(numbers()); // error, must be objects - ^^^^^^^^^ $Iterable. This type is incompatible with - array type. See lib: core.js:466 - Member 3: - polymorphic type: function type. See lib: core.js:467 - Error: - 29: function* numbers(): Iterable { - ^^^^^^ number. This type is incompatible with - object type. See lib: core.js:467 - - -Found 8 errors + ^^^^^^^^^^^^^^^^^^^^^^ constructor call + 29: function* numbers(): Iterable { + ^^^^^^ number. This type is incompatible with +object type. See lib: core.js:463 + + +Found 15 errors diff --git a/tests/core_tests/map.js b/tests/core_tests/map.js index dd3eca7716e..414b794c74c 100644 --- a/tests/core_tests/map.js +++ b/tests/core_tests/map.js @@ -21,7 +21,7 @@ let tests = [ // bad constructors function() { let x = new Map(['foo', 123]); // error - let y: Map = new Map([['foo', 123]]); // TODO: y no error? + let y: Map = new Map([['foo', 123]]); // error }, // get() diff --git a/tests/date/date.exp b/tests/date/date.exp index 10b636208cc..c96488e24c1 100644 --- a/tests/date/date.exp +++ b/tests/date/date.exp @@ -11,61 +11,61 @@ date.js:18 ^^^^^^^^^^^^ constructor call 18: new Date({}); ^^ object literal. This type is incompatible with -union: number | string. See lib: core.js:303 +union: number | string. See lib: core.js:305 Member 1: - number. See lib: core.js:303 + number. See lib: core.js:305 Error: 18: new Date({}); ^^ object literal. This type is incompatible with - number. See lib: core.js:303 + number. See lib: core.js:305 Member 2: - string. See lib: core.js:303 + string. See lib: core.js:305 Error: 18: new Date({}); ^^ object literal. This type is incompatible with - string. See lib: core.js:303 + string. See lib: core.js:305 date.js:19 19: new Date(2015, '6'); ^^^^^^^^^^^^^^^^^^^ constructor call 19: new Date(2015, '6'); ^^^ string. This type is incompatible with -number. See lib: core.js:303 +number. See lib: core.js:305 date.js:20 20: new Date(2015, 6, '18'); ^^^^^^^^^^^^^^^^^^^^^^^ constructor call 20: new Date(2015, 6, '18'); ^^^^ string. This type is incompatible with -number. See lib: core.js:303 +number. See lib: core.js:305 date.js:21 21: new Date(2015, 6, 18, '11'); ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructor call 21: new Date(2015, 6, 18, '11'); ^^^^ string. This type is incompatible with -number. See lib: core.js:303 +number. See lib: core.js:305 date.js:22 22: new Date(2015, 6, 18, 11, '55'); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructor call 22: new Date(2015, 6, 18, 11, '55'); ^^^^ string. This type is incompatible with -number. See lib: core.js:303 +number. See lib: core.js:305 date.js:23 23: new Date(2015, 6, 18, 11, 55, '42'); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructor call 23: new Date(2015, 6, 18, 11, 55, '42'); ^^^^ string. This type is incompatible with -number. See lib: core.js:303 +number. See lib: core.js:305 date.js:24 24: new Date(2015, 6, 18, 11, 55, 42, '999'); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructor call 24: new Date(2015, 6, 18, 11, 55, 42, '999'); ^^^^^ string. This type is incompatible with -number. See lib: core.js:303 +number. See lib: core.js:305 Found 8 errors diff --git a/tests/dom/dom.exp b/tests/dom/dom.exp index 2296b2001ed..16de77b9564 100644 --- a/tests/dom/dom.exp +++ b/tests/dom/dom.exp @@ -140,22 +140,21 @@ eventtarget.js:16 path2d.js:9 9: (path.arcTo(0, 0, 0, 0, 10, '20', 5): void); // invalid - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call of method `arcTo` + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call of method `arcTo`. Function cannot be called on any member of intersection type 9: (path.arcTo(0, 0, 0, 0, 10, '20', 5): void); // invalid - ^^^^ string. This type is incompatible with -union: number | undefined. See lib: dom.js:968 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ intersection Member 1: - number. See lib: dom.js:968 + function type. See lib: dom.js:967 Error: 9: (path.arcTo(0, 0, 0, 0, 10, '20', 5): void); // invalid ^^^^ string. This type is incompatible with - number. See lib: dom.js:968 - Member 2: undefined. See lib: dom.js:967 + Member 2: + function type. See lib: dom.js:968 Error: 9: (path.arcTo(0, 0, 0, 0, 10, '20', 5): void); // invalid ^^^^ string. This type is incompatible with - undefined. See lib: dom.js:967 + number. See lib: dom.js:968 registerElement.js:48 48: document.registerElement('custom-element', { @@ -701,867 +700,659 @@ traversal.js:30 traversal.js:183 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call of method `createNodeIterator`. Function cannot be called on any member of intersection type -183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ intersection + ^^^^^^^^ string. This type is incompatible with +union: typeof typeof-annotation '<>.FILTER_ACCEPT') | typeof typeof-annotation '<>.FILTER_REJECT') | typeof typeof-annotation '<>.FILTER_SKIP'). See lib: dom.js:1719 Member 1: - polymorphic type: function type. See lib: dom.js:495 + typeof typeof-annotation '<>.FILTER_ACCEPT'). See lib: dom.js:1719 Error: 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + ^^^^^^^^ string. This type is incompatible with + number literal `1`. See lib: dom.js:1719 + Member 2: + typeof typeof-annotation '<>.FILTER_REJECT'). See lib: dom.js:1720 + Error: + 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + ^^^^^^^^ string. This type is incompatible with + number literal `2`. See lib: dom.js:1720 + Member 3: + typeof typeof-annotation '<>.FILTER_SKIP'). See lib: dom.js:1721 + Error: + 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + ^^^^^^^^ string. This type is incompatible with + number literal `3`. See lib: dom.js:1721 + +traversal.js:185 +185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid + ^^^^^^^^ string. This type is incompatible with +union: typeof typeof-annotation '<>.FILTER_ACCEPT') | typeof typeof-annotation '<>.FILTER_REJECT') | typeof typeof-annotation '<>.FILTER_SKIP'). See lib: dom.js:1719 + Member 1: + typeof typeof-annotation '<>.FILTER_ACCEPT'). See lib: dom.js:1719 + Error: + 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid + ^^^^^^^^ string. This type is incompatible with + number literal `1`. See lib: dom.js:1719 + Member 2: + typeof typeof-annotation '<>.FILTER_REJECT'). See lib: dom.js:1720 + Error: + 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid + ^^^^^^^^ string. This type is incompatible with + number literal `2`. See lib: dom.js:1720 + Member 3: + typeof typeof-annotation '<>.FILTER_SKIP'). See lib: dom.js:1721 + Error: + 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid + ^^^^^^^^ string. This type is incompatible with + number literal `3`. See lib: dom.js:1721 + +traversal.js:186 +186: document.createNodeIterator(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call of method `createNodeIterator`. Function cannot be called on any member of intersection type +186: document.createNodeIterator(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ intersection + Member 1: + polymorphic type: function type. See lib: dom.js:495 + Error: + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with Attr. See lib: dom.js:495 Member 2: polymorphic type: function type. See lib: dom.js:503 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with Document. See lib: dom.js:503 Member 3: polymorphic type: function type. See lib: dom.js:504 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with Document. See lib: dom.js:504 Member 4: polymorphic type: function type. See lib: dom.js:505 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with Document. See lib: dom.js:505 Member 5: polymorphic type: function type. See lib: dom.js:506 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with Document. See lib: dom.js:506 Member 6: polymorphic type: function type. See lib: dom.js:507 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with Document. See lib: dom.js:507 Member 7: polymorphic type: function type. See lib: dom.js:508 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with Document. See lib: dom.js:508 Member 8: polymorphic type: function type. See lib: dom.js:509 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with Document. See lib: dom.js:509 Member 9: polymorphic type: function type. See lib: dom.js:510 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with Document. See lib: dom.js:510 Member 10: polymorphic type: function type. See lib: dom.js:511 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with Document. See lib: dom.js:511 Member 11: polymorphic type: function type. See lib: dom.js:512 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with Document. See lib: dom.js:512 Member 12: polymorphic type: function type. See lib: dom.js:513 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with Document. See lib: dom.js:513 Member 13: polymorphic type: function type. See lib: dom.js:514 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with Document. See lib: dom.js:514 Member 14: polymorphic type: function type. See lib: dom.js:515 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with Document. See lib: dom.js:515 Member 15: polymorphic type: function type. See lib: dom.js:516 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with Document. See lib: dom.js:516 Member 16: polymorphic type: function type. See lib: dom.js:517 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with Document. See lib: dom.js:517 Member 17: polymorphic type: function type. See lib: dom.js:518 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with Document. See lib: dom.js:518 Member 18: polymorphic type: function type. See lib: dom.js:519 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with Document. See lib: dom.js:519 Member 19: polymorphic type: function type. See lib: dom.js:520 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with Document. See lib: dom.js:520 Member 20: polymorphic type: function type. See lib: dom.js:521 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with Document. See lib: dom.js:521 Member 21: polymorphic type: function type. See lib: dom.js:522 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with Document. See lib: dom.js:522 Member 22: polymorphic type: function type. See lib: dom.js:523 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with Document. See lib: dom.js:523 Member 23: polymorphic type: function type. See lib: dom.js:524 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with Document. See lib: dom.js:524 Member 24: polymorphic type: function type. See lib: dom.js:525 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with Document. See lib: dom.js:525 Member 25: polymorphic type: function type. See lib: dom.js:526 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with Document. See lib: dom.js:526 Member 26: polymorphic type: function type. See lib: dom.js:554 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with DocumentFragment. See lib: dom.js:554 Member 27: polymorphic type: function type. See lib: dom.js:555 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with DocumentFragment. See lib: dom.js:555 Member 28: polymorphic type: function type. See lib: dom.js:556 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with DocumentFragment. See lib: dom.js:556 Member 29: polymorphic type: function type. See lib: dom.js:557 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with DocumentFragment. See lib: dom.js:557 Member 30: polymorphic type: function type. See lib: dom.js:558 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with DocumentFragment. See lib: dom.js:558 Member 31: polymorphic type: function type. See lib: dom.js:559 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with DocumentFragment. See lib: dom.js:559 Member 32: polymorphic type: function type. See lib: dom.js:560 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with DocumentFragment. See lib: dom.js:560 Member 33: polymorphic type: function type. See lib: dom.js:561 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with DocumentFragment. See lib: dom.js:561 Member 34: polymorphic type: function type. See lib: dom.js:574 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^ number. Expected number literal `1`, got `-1` instead number literal `1`. See lib: dom.js:574 Member 35: polymorphic type: function type. See lib: dom.js:575 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^ number. Expected number literal `4`, got `-1` instead number literal `4`. See lib: dom.js:575 Member 36: polymorphic type: function type. See lib: dom.js:576 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^ number. Expected number literal `5`, got `-1` instead number literal `5`. See lib: dom.js:576 Member 37: polymorphic type: function type. See lib: dom.js:577 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^ number. Expected number literal `128`, got `-1` instead number literal `128`. See lib: dom.js:577 Member 38: polymorphic type: function type. See lib: dom.js:578 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^ number. Expected number literal `129`, got `-1` instead number literal `129`. See lib: dom.js:578 Member 39: polymorphic type: function type. See lib: dom.js:579 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^ number. Expected number literal `132`, got `-1` instead number literal `132`. See lib: dom.js:579 Member 40: polymorphic type: function type. See lib: dom.js:580 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^ number. Expected number literal `133`, got `-1` instead number literal `133`. See lib: dom.js:580 Member 41: polymorphic type: function type. See lib: dom.js:581 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid - ^^^^^^^^^^^^^^^^ arrow function. This type is incompatible with + 186: document.createNodeIterator(document.body, -1, {}); // invalid + ^^ object literal. This type is incompatible with union: NodeFilterCallback | object type. See lib: dom.js:581 Member 1: NodeFilterCallback. See lib: dom.js:1723 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid - ^^^^^^^^ string. This type is incompatible with - union: typeof typeof-annotation '<>.FILTER_ACCEPT') | typeof typeof-annotation '<>.FILTER_REJECT') | typeof typeof-annotation '<>.FILTER_SKIP'). See lib: dom.js:1719 - Member 1: - typeof typeof-annotation '<>.FILTER_ACCEPT'). See lib: dom.js:1719 - Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid - ^^^^^^^^ string. This type is incompatible with - number literal `1`. See lib: dom.js:1719 - Member 2: - typeof typeof-annotation '<>.FILTER_REJECT'). See lib: dom.js:1720 - Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid - ^^^^^^^^ string. This type is incompatible with - number literal `2`. See lib: dom.js:1720 - Member 3: - typeof typeof-annotation '<>.FILTER_SKIP'). See lib: dom.js:1721 - Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid - ^^^^^^^^ string. This type is incompatible with - number literal `3`. See lib: dom.js:1721 + function type. Callable signature not found in. See lib: dom.js:1723 + 186: document.createNodeIterator(document.body, -1, {}); // invalid + ^^ object literal Member 2: object type. See lib: dom.js:1723 Error: property `accept`. Property not found in. See lib: dom.js:1723 - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid - ^^^^^^^^^^^^^^^^ arrow function + 186: document.createNodeIterator(document.body, -1, {}); // invalid + ^^ object literal Member 42: polymorphic type: function type. See lib: dom.js:592 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with Document. See lib: dom.js:592 Member 43: polymorphic type: function type. See lib: dom.js:596 Error: - 183: document.createNodeIterator(document.body, -1, node => 'accept'); // invalid + 186: document.createNodeIterator(document.body, -1, {}); // invalid ^^ number. This type is incompatible with undefined. See lib: dom.js:596 -traversal.js:185 -185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call of method `createNodeIterator`. Function cannot be called on any member of intersection type -185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ intersection +traversal.js:190 +190: document.createTreeWalker(document.body, -1, node => 'accept'); // invalid + ^^^^^^^^ string. This type is incompatible with +union: typeof typeof-annotation '<>.FILTER_ACCEPT') | typeof typeof-annotation '<>.FILTER_REJECT') | typeof typeof-annotation '<>.FILTER_SKIP'). See lib: dom.js:1719 Member 1: - polymorphic type: function type. See lib: dom.js:495 + typeof typeof-annotation '<>.FILTER_ACCEPT'). See lib: dom.js:1719 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Attr. See lib: dom.js:495 + 190: document.createTreeWalker(document.body, -1, node => 'accept'); // invalid + ^^^^^^^^ string. This type is incompatible with + number literal `1`. See lib: dom.js:1719 Member 2: - polymorphic type: function type. See lib: dom.js:503 + typeof typeof-annotation '<>.FILTER_REJECT'). See lib: dom.js:1720 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:503 + 190: document.createTreeWalker(document.body, -1, node => 'accept'); // invalid + ^^^^^^^^ string. This type is incompatible with + number literal `2`. See lib: dom.js:1720 Member 3: - polymorphic type: function type. See lib: dom.js:504 + typeof typeof-annotation '<>.FILTER_SKIP'). See lib: dom.js:1721 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:504 + 190: document.createTreeWalker(document.body, -1, node => 'accept'); // invalid + ^^^^^^^^ string. This type is incompatible with + number literal `3`. See lib: dom.js:1721 + +traversal.js:192 +192: document.createTreeWalker(document.body, -1, { accept: node => 'accept' }); // invalid + ^^^^^^^^ string. This type is incompatible with +union: typeof typeof-annotation '<>.FILTER_ACCEPT') | typeof typeof-annotation '<>.FILTER_REJECT') | typeof typeof-annotation '<>.FILTER_SKIP'). See lib: dom.js:1719 + Member 1: + typeof typeof-annotation '<>.FILTER_ACCEPT'). See lib: dom.js:1719 + Error: + 192: document.createTreeWalker(document.body, -1, { accept: node => 'accept' }); // invalid + ^^^^^^^^ string. This type is incompatible with + number literal `1`. See lib: dom.js:1719 + Member 2: + typeof typeof-annotation '<>.FILTER_REJECT'). See lib: dom.js:1720 + Error: + 192: document.createTreeWalker(document.body, -1, { accept: node => 'accept' }); // invalid + ^^^^^^^^ string. This type is incompatible with + number literal `2`. See lib: dom.js:1720 + Member 3: + typeof typeof-annotation '<>.FILTER_SKIP'). See lib: dom.js:1721 + Error: + 192: document.createTreeWalker(document.body, -1, { accept: node => 'accept' }); // invalid + ^^^^^^^^ string. This type is incompatible with + number literal `3`. See lib: dom.js:1721 + +traversal.js:193 +193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call of method `createTreeWalker`. Function cannot be called on any member of intersection type +193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ intersection + Member 1: + polymorphic type: function type. See lib: dom.js:496 + Error: + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + Attr. See lib: dom.js:496 + Member 2: + polymorphic type: function type. See lib: dom.js:527 + Error: + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + Document. See lib: dom.js:527 + Member 3: + polymorphic type: function type. See lib: dom.js:528 + Error: + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + Document. See lib: dom.js:528 Member 4: - polymorphic type: function type. See lib: dom.js:505 + polymorphic type: function type. See lib: dom.js:529 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:505 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + Document. See lib: dom.js:529 Member 5: - polymorphic type: function type. See lib: dom.js:506 + polymorphic type: function type. See lib: dom.js:530 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:506 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + Document. See lib: dom.js:530 Member 6: - polymorphic type: function type. See lib: dom.js:507 + polymorphic type: function type. See lib: dom.js:531 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:507 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + Document. See lib: dom.js:531 Member 7: - polymorphic type: function type. See lib: dom.js:508 + polymorphic type: function type. See lib: dom.js:532 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:508 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + Document. See lib: dom.js:532 Member 8: - polymorphic type: function type. See lib: dom.js:509 + polymorphic type: function type. See lib: dom.js:533 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:509 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + Document. See lib: dom.js:533 Member 9: - polymorphic type: function type. See lib: dom.js:510 + polymorphic type: function type. See lib: dom.js:534 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:510 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + Document. See lib: dom.js:534 Member 10: - polymorphic type: function type. See lib: dom.js:511 + polymorphic type: function type. See lib: dom.js:535 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:511 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + Document. See lib: dom.js:535 Member 11: - polymorphic type: function type. See lib: dom.js:512 + polymorphic type: function type. See lib: dom.js:536 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:512 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + Document. See lib: dom.js:536 Member 12: - polymorphic type: function type. See lib: dom.js:513 + polymorphic type: function type. See lib: dom.js:537 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:513 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + Document. See lib: dom.js:537 Member 13: - polymorphic type: function type. See lib: dom.js:514 + polymorphic type: function type. See lib: dom.js:538 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:514 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + Document. See lib: dom.js:538 Member 14: - polymorphic type: function type. See lib: dom.js:515 + polymorphic type: function type. See lib: dom.js:539 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:515 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + Document. See lib: dom.js:539 Member 15: - polymorphic type: function type. See lib: dom.js:516 + polymorphic type: function type. See lib: dom.js:540 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:516 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + Document. See lib: dom.js:540 Member 16: - polymorphic type: function type. See lib: dom.js:517 + polymorphic type: function type. See lib: dom.js:541 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:517 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + Document. See lib: dom.js:541 Member 17: - polymorphic type: function type. See lib: dom.js:518 + polymorphic type: function type. See lib: dom.js:542 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:518 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + Document. See lib: dom.js:542 Member 18: - polymorphic type: function type. See lib: dom.js:519 + polymorphic type: function type. See lib: dom.js:543 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:519 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + Document. See lib: dom.js:543 Member 19: - polymorphic type: function type. See lib: dom.js:520 + polymorphic type: function type. See lib: dom.js:544 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:520 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + Document. See lib: dom.js:544 Member 20: - polymorphic type: function type. See lib: dom.js:521 + polymorphic type: function type. See lib: dom.js:545 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:521 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + Document. See lib: dom.js:545 Member 21: - polymorphic type: function type. See lib: dom.js:522 + polymorphic type: function type. See lib: dom.js:546 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:522 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + Document. See lib: dom.js:546 Member 22: - polymorphic type: function type. See lib: dom.js:523 + polymorphic type: function type. See lib: dom.js:547 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:523 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + Document. See lib: dom.js:547 Member 23: - polymorphic type: function type. See lib: dom.js:524 + polymorphic type: function type. See lib: dom.js:548 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:524 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + Document. See lib: dom.js:548 Member 24: - polymorphic type: function type. See lib: dom.js:525 + polymorphic type: function type. See lib: dom.js:549 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:525 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + Document. See lib: dom.js:549 Member 25: - polymorphic type: function type. See lib: dom.js:526 + polymorphic type: function type. See lib: dom.js:550 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:526 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + Document. See lib: dom.js:550 Member 26: - polymorphic type: function type. See lib: dom.js:554 + polymorphic type: function type. See lib: dom.js:562 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - DocumentFragment. See lib: dom.js:554 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + DocumentFragment. See lib: dom.js:562 Member 27: - polymorphic type: function type. See lib: dom.js:555 + polymorphic type: function type. See lib: dom.js:563 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - DocumentFragment. See lib: dom.js:555 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + DocumentFragment. See lib: dom.js:563 Member 28: - polymorphic type: function type. See lib: dom.js:556 + polymorphic type: function type. See lib: dom.js:564 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - DocumentFragment. See lib: dom.js:556 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + DocumentFragment. See lib: dom.js:564 Member 29: - polymorphic type: function type. See lib: dom.js:557 + polymorphic type: function type. See lib: dom.js:565 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - DocumentFragment. See lib: dom.js:557 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + DocumentFragment. See lib: dom.js:565 Member 30: - polymorphic type: function type. See lib: dom.js:558 + polymorphic type: function type. See lib: dom.js:566 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - DocumentFragment. See lib: dom.js:558 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + DocumentFragment. See lib: dom.js:566 Member 31: - polymorphic type: function type. See lib: dom.js:559 + polymorphic type: function type. See lib: dom.js:567 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - DocumentFragment. See lib: dom.js:559 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + DocumentFragment. See lib: dom.js:567 Member 32: - polymorphic type: function type. See lib: dom.js:560 + polymorphic type: function type. See lib: dom.js:568 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - DocumentFragment. See lib: dom.js:560 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + DocumentFragment. See lib: dom.js:568 Member 33: - polymorphic type: function type. See lib: dom.js:561 + polymorphic type: function type. See lib: dom.js:569 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - DocumentFragment. See lib: dom.js:561 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with + DocumentFragment. See lib: dom.js:569 Member 34: - polymorphic type: function type. See lib: dom.js:574 + polymorphic type: function type. See lib: dom.js:582 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^ number. Expected number literal `1`, got `-1` instead - number literal `1`. See lib: dom.js:574 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^ number. Expected number literal `1`, got `-1` instead + number literal `1`. See lib: dom.js:582 Member 35: - polymorphic type: function type. See lib: dom.js:575 + polymorphic type: function type. See lib: dom.js:583 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^ number. Expected number literal `4`, got `-1` instead - number literal `4`. See lib: dom.js:575 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^ number. Expected number literal `4`, got `-1` instead + number literal `4`. See lib: dom.js:583 Member 36: - polymorphic type: function type. See lib: dom.js:576 + polymorphic type: function type. See lib: dom.js:584 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^ number. Expected number literal `5`, got `-1` instead - number literal `5`. See lib: dom.js:576 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^ number. Expected number literal `5`, got `-1` instead + number literal `5`. See lib: dom.js:584 Member 37: - polymorphic type: function type. See lib: dom.js:577 + polymorphic type: function type. See lib: dom.js:585 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^ number. Expected number literal `128`, got `-1` instead - number literal `128`. See lib: dom.js:577 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^ number. Expected number literal `128`, got `-1` instead + number literal `128`. See lib: dom.js:585 Member 38: - polymorphic type: function type. See lib: dom.js:578 + polymorphic type: function type. See lib: dom.js:586 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^ number. Expected number literal `129`, got `-1` instead - number literal `129`. See lib: dom.js:578 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^ number. Expected number literal `129`, got `-1` instead + number literal `129`. See lib: dom.js:586 Member 39: - polymorphic type: function type. See lib: dom.js:579 + polymorphic type: function type. See lib: dom.js:587 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^ number. Expected number literal `132`, got `-1` instead - number literal `132`. See lib: dom.js:579 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^ number. Expected number literal `132`, got `-1` instead + number literal `132`. See lib: dom.js:587 Member 40: - polymorphic type: function type. See lib: dom.js:580 + polymorphic type: function type. See lib: dom.js:588 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^ number. Expected number literal `133`, got `-1` instead - number literal `133`. See lib: dom.js:580 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^ number. Expected number literal `133`, got `-1` instead + number literal `133`. See lib: dom.js:588 Member 41: - polymorphic type: function type. See lib: dom.js:581 + polymorphic type: function type. See lib: dom.js:589 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ object literal. This type is incompatible with - union: NodeFilterCallback | object type. See lib: dom.js:581 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^ object literal. This type is incompatible with + union: NodeFilterCallback | object type. See lib: dom.js:589 Member 1: NodeFilterCallback. See lib: dom.js:1723 Error: function type. Callable signature not found in. See lib: dom.js:1723 - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ object literal + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^ object literal Member 2: object type. See lib: dom.js:1723 Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^ string. This type is incompatible with - union: typeof typeof-annotation '<>.FILTER_ACCEPT') | typeof typeof-annotation '<>.FILTER_REJECT') | typeof typeof-annotation '<>.FILTER_SKIP'). See lib: dom.js:1719 - Member 1: - typeof typeof-annotation '<>.FILTER_ACCEPT'). See lib: dom.js:1719 - Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^ string. This type is incompatible with - number literal `1`. See lib: dom.js:1719 - Member 2: - typeof typeof-annotation '<>.FILTER_REJECT'). See lib: dom.js:1720 - Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^ string. This type is incompatible with - number literal `2`. See lib: dom.js:1720 - Member 3: - typeof typeof-annotation '<>.FILTER_SKIP'). See lib: dom.js:1721 - Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^ string. This type is incompatible with - number literal `3`. See lib: dom.js:1721 + property `accept`. Property not found in. See lib: dom.js:1723 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^ object literal Member 42: - polymorphic type: function type. See lib: dom.js:592 - Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:592 - Member 43: - polymorphic type: function type. See lib: dom.js:596 - Error: - 185: document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid - ^^ number. This type is incompatible with - undefined. See lib: dom.js:596 - -traversal.js:186 -186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call of method `createNodeIterator`. Function cannot be called on any member of intersection type -186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ intersection - Member 1: - polymorphic type: function type. See lib: dom.js:495 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Attr. See lib: dom.js:495 - Member 2: - polymorphic type: function type. See lib: dom.js:503 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:503 - Member 3: - polymorphic type: function type. See lib: dom.js:504 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:504 - Member 4: - polymorphic type: function type. See lib: dom.js:505 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:505 - Member 5: - polymorphic type: function type. See lib: dom.js:506 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:506 - Member 6: - polymorphic type: function type. See lib: dom.js:507 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:507 - Member 7: - polymorphic type: function type. See lib: dom.js:508 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:508 - Member 8: - polymorphic type: function type. See lib: dom.js:509 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:509 - Member 9: - polymorphic type: function type. See lib: dom.js:510 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:510 - Member 10: - polymorphic type: function type. See lib: dom.js:511 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:511 - Member 11: - polymorphic type: function type. See lib: dom.js:512 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:512 - Member 12: - polymorphic type: function type. See lib: dom.js:513 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:513 - Member 13: - polymorphic type: function type. See lib: dom.js:514 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:514 - Member 14: - polymorphic type: function type. See lib: dom.js:515 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:515 - Member 15: - polymorphic type: function type. See lib: dom.js:516 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:516 - Member 16: - polymorphic type: function type. See lib: dom.js:517 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:517 - Member 17: - polymorphic type: function type. See lib: dom.js:518 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:518 - Member 18: - polymorphic type: function type. See lib: dom.js:519 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:519 - Member 19: - polymorphic type: function type. See lib: dom.js:520 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:520 - Member 20: - polymorphic type: function type. See lib: dom.js:521 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:521 - Member 21: - polymorphic type: function type. See lib: dom.js:522 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:522 - Member 22: - polymorphic type: function type. See lib: dom.js:523 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:523 - Member 23: - polymorphic type: function type. See lib: dom.js:524 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:524 - Member 24: - polymorphic type: function type. See lib: dom.js:525 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:525 - Member 25: - polymorphic type: function type. See lib: dom.js:526 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:526 - Member 26: - polymorphic type: function type. See lib: dom.js:554 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - DocumentFragment. See lib: dom.js:554 - Member 27: - polymorphic type: function type. See lib: dom.js:555 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - DocumentFragment. See lib: dom.js:555 - Member 28: - polymorphic type: function type. See lib: dom.js:556 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - DocumentFragment. See lib: dom.js:556 - Member 29: - polymorphic type: function type. See lib: dom.js:557 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - DocumentFragment. See lib: dom.js:557 - Member 30: - polymorphic type: function type. See lib: dom.js:558 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - DocumentFragment. See lib: dom.js:558 - Member 31: - polymorphic type: function type. See lib: dom.js:559 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - DocumentFragment. See lib: dom.js:559 - Member 32: - polymorphic type: function type. See lib: dom.js:560 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - DocumentFragment. See lib: dom.js:560 - Member 33: - polymorphic type: function type. See lib: dom.js:561 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - DocumentFragment. See lib: dom.js:561 - Member 34: - polymorphic type: function type. See lib: dom.js:574 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^ number. Expected number literal `1`, got `-1` instead - number literal `1`. See lib: dom.js:574 - Member 35: - polymorphic type: function type. See lib: dom.js:575 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^ number. Expected number literal `4`, got `-1` instead - number literal `4`. See lib: dom.js:575 - Member 36: - polymorphic type: function type. See lib: dom.js:576 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^ number. Expected number literal `5`, got `-1` instead - number literal `5`. See lib: dom.js:576 - Member 37: - polymorphic type: function type. See lib: dom.js:577 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^ number. Expected number literal `128`, got `-1` instead - number literal `128`. See lib: dom.js:577 - Member 38: - polymorphic type: function type. See lib: dom.js:578 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^ number. Expected number literal `129`, got `-1` instead - number literal `129`. See lib: dom.js:578 - Member 39: - polymorphic type: function type. See lib: dom.js:579 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^ number. Expected number literal `132`, got `-1` instead - number literal `132`. See lib: dom.js:579 - Member 40: - polymorphic type: function type. See lib: dom.js:580 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^ number. Expected number literal `133`, got `-1` instead - number literal `133`. See lib: dom.js:580 - Member 41: - polymorphic type: function type. See lib: dom.js:581 + polymorphic type: function type. See lib: dom.js:593 Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^ object literal. This type is incompatible with - union: NodeFilterCallback | object type. See lib: dom.js:581 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^ object literal. This type is incompatible with + union: NodeFilterCallback | object type. See lib: dom.js:593 Member 1: NodeFilterCallback. See lib: dom.js:1723 Error: function type. Callable signature not found in. See lib: dom.js:1723 - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^ object literal + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^ object literal Member 2: object type. See lib: dom.js:1723 Error: property `accept`. Property not found in. See lib: dom.js:1723 - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^ object literal - Member 42: - polymorphic type: function type. See lib: dom.js:592 - Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^^^^^^^^^^^^ HTMLElement. This type is incompatible with - Document. See lib: dom.js:592 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^ object literal Member 43: - polymorphic type: function type. See lib: dom.js:596 + polymorphic type: function type. See lib: dom.js:597 Error: - 186: document.createNodeIterator(document.body, -1, {}); // invalid - ^^ number. This type is incompatible with - undefined. See lib: dom.js:596 + 193: document.createTreeWalker(document.body, -1, {}); // invalid + ^^ number. This type is incompatible with + undefined. See lib: dom.js:597 -Found 18 errors +Found 21 errors diff --git a/tests/dump-types/dump-types.exp b/tests/dump-types/dump-types.exp index c473926ff1a..e549d12eacf 100644 --- a/tests/dump-types/dump-types.exp +++ b/tests/dump-types/dump-types.exp @@ -1,2 +1,2 @@ -[{"type":"number","reasons":[{"desc":"number","loc":{"source":"test.js","type":"SourceFile","start":{"line":2,"column":11,"offset":19},"end":{"line":2,"column":29,"offset":38}},"path":"test.js","line":2,"endline":2,"start":11,"end":29}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":2,"column":5,"offset":13},"end":{"line":2,"column":7,"offset":16}},"path":"test.js","line":2,"endline":2,"start":5,"end":7},{"type":"number","reasons":[{"desc":"number","loc":{"source":"test.js","type":"SourceFile","start":{"line":2,"column":11,"offset":19},"end":{"line":2,"column":29,"offset":38}},"path":"test.js","line":2,"endline":2,"start":11,"end":29}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":2,"column":11,"offset":19},"end":{"line":2,"column":29,"offset":38}},"path":"test.js","line":2,"endline":2,"start":11,"end":29},{"type":"(x: number) => void","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":3,"column":10,"offset":49},"end":{"line":3,"column":12,"offset":52}},"path":"test.js","line":3,"endline":3,"start":10,"end":12},{"type":"number","reasons":[{"desc":"number","loc":{"source":"test.js","type":"SourceFile","start":{"line":4,"column":5,"offset":64},"end":{"line":4,"column":5,"offset":65}},"path":"test.js","line":4,"endline":4,"start":5,"end":5}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":3,"column":14,"offset":53},"end":{"line":3,"column":14,"offset":54}},"path":"test.js","line":3,"endline":3,"start":14,"end":14},{"type":"(x: number) => void","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":4,"column":1,"offset":60},"end":{"line":4,"column":3,"offset":63}},"path":"test.js","line":4,"endline":4,"start":1,"end":3},{"type":"void","reasons":[{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":4,"column":1,"offset":60},"end":{"line":4,"column":6,"offset":66}},"path":"test.js","line":4,"endline":4,"start":1,"end":6}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":4,"column":1,"offset":60},"end":{"line":4,"column":6,"offset":66}},"path":"test.js","line":4,"endline":4,"start":1,"end":6},{"type":"number","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":4,"column":5,"offset":64},"end":{"line":4,"column":5,"offset":65}},"path":"test.js","line":4,"endline":4,"start":5,"end":5},{"type":"string","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":5,"column":5,"offset":72},"end":{"line":5,"column":12,"offset":80}},"path":"test.js","line":5,"endline":5,"start":5,"end":12},{"type":"number","reasons":[{"desc":"number","loc":{"source":"test.js","type":"SourceFile","start":{"line":5,"column":16,"offset":83},"end":{"line":5,"column":18,"offset":86}},"path":"test.js","line":5,"endline":5,"start":16,"end":18}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":5,"column":16,"offset":83},"end":{"line":5,"column":18,"offset":86}},"path":"test.js","line":5,"endline":5,"start":16,"end":18},{"type":"(x: ) => ","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":7,"column":10,"offset":98},"end":{"line":7,"column":20,"offset":109}},"path":"test.js","line":7,"endline":7,"start":10,"end":20},{"type":"","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":7,"column":22,"offset":110},"end":{"line":7,"column":22,"offset":111}},"path":"test.js","line":7,"endline":7,"start":22,"end":22},{"type":"","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":8,"column":10,"offset":124},"end":{"line":8,"column":10,"offset":125}},"path":"test.js","line":8,"endline":8,"start":10,"end":10},{"type":"(val: string | null | void | Object) => string | void | Object","reasons":[{"desc":"arrow function","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":25,"offset":189},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":25,"end":61}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":7,"offset":171},"end":{"line":12,"column":21,"offset":186}},"path":"test.js","line":12,"endline":12,"start":7,"end":21},{"type":"string | null | void | Object","reasons":[{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":50,"offset":333},"end":{"line":15,"column":50,"offset":334}},"path":"test.js","line":15,"endline":15,"start":50,"end":50},{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":50,"offset":278},"end":{"line":14,"column":50,"offset":279}},"path":"test.js","line":14,"endline":14,"start":50,"end":50},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":50,"offset":443},"end":{"line":17,"column":50,"offset":444}},"path":"test.js","line":17,"endline":17,"start":50,"end":50},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":50,"offset":388},"end":{"line":16,"column":50,"offset":389}},"path":"test.js","line":16,"endline":16,"start":50,"end":50},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":50,"offset":333},"end":{"line":15,"column":50,"offset":334}},"path":"test.js","line":15,"endline":15,"start":50,"end":50},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":50,"offset":278},"end":{"line":14,"column":50,"offset":279}},"path":"test.js","line":14,"endline":14,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":50,"offset":443},"end":{"line":17,"column":50,"offset":444}},"path":"test.js","line":17,"endline":17,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":50,"offset":388},"end":{"line":16,"column":50,"offset":389}},"path":"test.js","line":16,"endline":16,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":50,"offset":333},"end":{"line":15,"column":50,"offset":334}},"path":"test.js","line":15,"endline":15,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":50,"offset":278},"end":{"line":14,"column":50,"offset":279}},"path":"test.js","line":14,"endline":14,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":50,"offset":443},"end":{"line":17,"column":50,"offset":444}},"path":"test.js","line":17,"endline":17,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":50,"offset":388},"end":{"line":16,"column":50,"offset":389}},"path":"test.js","line":16,"endline":16,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":50,"offset":333},"end":{"line":15,"column":50,"offset":334}},"path":"test.js","line":15,"endline":15,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":50,"offset":278},"end":{"line":14,"column":50,"offset":279}},"path":"test.js","line":14,"endline":14,"start":50,"end":50},{"desc":"","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":50,"offset":443},"end":{"line":17,"column":50,"offset":444}},"path":"test.js","line":17,"endline":17,"start":50,"end":50},{"desc":"","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":50,"offset":388},"end":{"line":16,"column":50,"offset":389}},"path":"test.js","line":16,"endline":16,"start":50,"end":50},{"desc":"","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":50,"offset":333},"end":{"line":15,"column":50,"offset":334}},"path":"test.js","line":15,"endline":15,"start":50,"end":50},{"desc":"","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":50,"offset":278},"end":{"line":14,"column":50,"offset":279}},"path":"test.js","line":14,"endline":14,"start":50,"end":50},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":50,"offset":443},"end":{"line":17,"column":50,"offset":444}},"path":"test.js","line":17,"endline":17,"start":50,"end":50},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":50,"offset":388},"end":{"line":16,"column":50,"offset":389}},"path":"test.js","line":16,"endline":16,"start":50,"end":50}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":25,"offset":189},"end":{"line":12,"column":27,"offset":192}},"path":"test.js","line":12,"endline":12,"start":25,"end":27},{"type":"(val: string | null | void | Object) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":25,"offset":189},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":25,"end":61},{"type":"string | null | void | Object","reasons":[{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":34,"offset":199}},"path":"test.js","line":12,"endline":12,"start":32,"end":34},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":34,"offset":199}},"path":"test.js","line":12,"endline":12,"start":32,"end":34},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":34,"offset":199}},"path":"test.js","line":12,"endline":12,"start":32,"end":34},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":34,"offset":199}},"path":"test.js","line":12,"endline":12,"start":32,"end":34},{"desc":"","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":34,"offset":199}},"path":"test.js","line":12,"endline":12,"start":32,"end":34},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":34,"offset":199}},"path":"test.js","line":12,"endline":12,"start":32,"end":34}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":34,"offset":199}},"path":"test.js","line":12,"endline":12,"start":32,"end":34},{"type":"string | void | Object","reasons":[{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":59,"offset":223},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":59,"end":61},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":59,"offset":223},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":59,"end":61},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":47,"offset":211},"end":{"line":12,"column":55,"offset":220}},"path":"test.js","line":12,"endline":12,"start":47,"end":55},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":59,"offset":223},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":59,"end":61},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":59,"offset":223},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":59,"end":61}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":32,"end":61},{"type":"null","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":40,"offset":204},"end":{"line":12,"column":43,"offset":208}},"path":"test.js","line":12,"endline":12,"start":40,"end":43},{"type":"void","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":47,"offset":211},"end":{"line":12,"column":55,"offset":220}},"path":"test.js","line":12,"endline":12,"start":47,"end":55},{"type":"string | void | Object","reasons":[{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":59,"offset":223},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":59,"end":61},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":59,"offset":223},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":59,"end":61},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":59,"offset":223},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":59,"end":61},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":59,"offset":223},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":59,"end":61}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":59,"offset":223},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":59,"end":61},{"type":"(x: ?Object) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":10,"offset":238},"end":{"line":14,"column":11,"offset":240}},"path":"test.js","line":14,"endline":14,"start":10,"end":11},{"type":"?Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":13,"offset":241},"end":{"line":14,"column":22,"offset":251}},"path":"test.js","line":14,"endline":14,"start":13,"end":22},{"type":"(val: string | null | void | Object) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":34,"offset":262},"end":{"line":14,"column":48,"offset":277}},"path":"test.js","line":14,"endline":14,"start":34,"end":48},{"type":"string | void | Object","reasons":[{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":34,"offset":262},"end":{"line":14,"column":51,"offset":280}},"path":"test.js","line":14,"endline":14,"start":34,"end":51},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":34,"offset":262},"end":{"line":14,"column":51,"offset":280}},"path":"test.js","line":14,"endline":14,"start":34,"end":51},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":34,"offset":262},"end":{"line":14,"column":51,"offset":280}},"path":"test.js","line":14,"endline":14,"start":34,"end":51},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":34,"offset":262},"end":{"line":14,"column":51,"offset":280}},"path":"test.js","line":14,"endline":14,"start":34,"end":51}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":34,"offset":262},"end":{"line":14,"column":51,"offset":280}},"path":"test.js","line":14,"endline":14,"start":34,"end":51},{"type":"?Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":50,"offset":278},"end":{"line":14,"column":50,"offset":279}},"path":"test.js","line":14,"endline":14,"start":50,"end":50},{"type":"(x: ?Object) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":10,"offset":293},"end":{"line":15,"column":11,"offset":295}},"path":"test.js","line":15,"endline":15,"start":10,"end":11},{"type":"?Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":13,"offset":296},"end":{"line":15,"column":22,"offset":306}},"path":"test.js","line":15,"endline":15,"start":13,"end":22},{"type":"(val: string | null | void | Object) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":34,"offset":317},"end":{"line":15,"column":48,"offset":332}},"path":"test.js","line":15,"endline":15,"start":34,"end":48},{"type":"string | void | Object","reasons":[{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":34,"offset":317},"end":{"line":15,"column":51,"offset":335}},"path":"test.js","line":15,"endline":15,"start":34,"end":51},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":34,"offset":317},"end":{"line":15,"column":51,"offset":335}},"path":"test.js","line":15,"endline":15,"start":34,"end":51},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":34,"offset":317},"end":{"line":15,"column":51,"offset":335}},"path":"test.js","line":15,"endline":15,"start":34,"end":51},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":34,"offset":317},"end":{"line":15,"column":51,"offset":335}},"path":"test.js","line":15,"endline":15,"start":34,"end":51}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":34,"offset":317},"end":{"line":15,"column":51,"offset":335}},"path":"test.js","line":15,"endline":15,"start":34,"end":51},{"type":"?Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":50,"offset":333},"end":{"line":15,"column":50,"offset":334}},"path":"test.js","line":15,"endline":15,"start":50,"end":50},{"type":"(x: ?string) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":10,"offset":348},"end":{"line":16,"column":11,"offset":350}},"path":"test.js","line":16,"endline":16,"start":10,"end":11},{"type":"?string","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":13,"offset":351},"end":{"line":16,"column":22,"offset":361}},"path":"test.js","line":16,"endline":16,"start":13,"end":22},{"type":"(val: string | null | void | Object) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":34,"offset":372},"end":{"line":16,"column":48,"offset":387}},"path":"test.js","line":16,"endline":16,"start":34,"end":48},{"type":"string | void | Object","reasons":[{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":34,"offset":372},"end":{"line":16,"column":51,"offset":390}},"path":"test.js","line":16,"endline":16,"start":34,"end":51},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":34,"offset":372},"end":{"line":16,"column":51,"offset":390}},"path":"test.js","line":16,"endline":16,"start":34,"end":51},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":34,"offset":372},"end":{"line":16,"column":51,"offset":390}},"path":"test.js","line":16,"endline":16,"start":34,"end":51},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":34,"offset":372},"end":{"line":16,"column":51,"offset":390}},"path":"test.js","line":16,"endline":16,"start":34,"end":51}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":34,"offset":372},"end":{"line":16,"column":51,"offset":390}},"path":"test.js","line":16,"endline":16,"start":34,"end":51},{"type":"?string","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":50,"offset":388},"end":{"line":16,"column":50,"offset":389}},"path":"test.js","line":16,"endline":16,"start":50,"end":50},{"type":"(x: ?string) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":10,"offset":403},"end":{"line":17,"column":11,"offset":405}},"path":"test.js","line":17,"endline":17,"start":10,"end":11},{"type":"?string","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":13,"offset":406},"end":{"line":17,"column":22,"offset":416}},"path":"test.js","line":17,"endline":17,"start":13,"end":22},{"type":"(val: string | null | void | Object) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":34,"offset":427},"end":{"line":17,"column":48,"offset":442}},"path":"test.js","line":17,"endline":17,"start":34,"end":48},{"type":"string | void | Object","reasons":[{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":34,"offset":427},"end":{"line":17,"column":51,"offset":445}},"path":"test.js","line":17,"endline":17,"start":34,"end":51},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":34,"offset":427},"end":{"line":17,"column":51,"offset":445}},"path":"test.js","line":17,"endline":17,"start":34,"end":51},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":34,"offset":427},"end":{"line":17,"column":51,"offset":445}},"path":"test.js","line":17,"endline":17,"start":34,"end":51},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":34,"offset":427},"end":{"line":17,"column":51,"offset":445}},"path":"test.js","line":17,"endline":17,"start":34,"end":51}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":34,"offset":427},"end":{"line":17,"column":51,"offset":445}},"path":"test.js","line":17,"endline":17,"start":34,"end":51},{"type":"?string","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":50,"offset":443},"end":{"line":17,"column":50,"offset":444}},"path":"test.js","line":17,"endline":17,"start":50,"end":50}] -[{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"number\"\n },\n \"kind\":\"NumT\"\n}","type":"number","reasons":[{"desc":"number","loc":{"source":"test.js","type":"SourceFile","start":{"line":2,"column":11,"offset":19},"end":{"line":2,"column":29,"offset":38}},"path":"test.js","line":2,"endline":2,"start":11,"end":29}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":2,"column":5,"offset":13},"end":{"line":2,"column":7,"offset":16}},"path":"test.js","line":2,"endline":2,"start":5,"end":7},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"number\"\n },\n \"kind\":\"NumT\"\n}","type":"number","reasons":[{"desc":"number","loc":{"source":"test.js","type":"SourceFile","start":{"line":2,"column":11,"offset":19},"end":{"line":2,"column":29,"offset":38}},"path":"test.js","line":2,"endline":2,"start":11,"end":29}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":2,"column":11,"offset":19},"end":{"line":2,"column":29,"offset":38}},"path":"test.js","line":2,"endline":2,"start":11,"end":29},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"function\"\n },\n \"kind\":\"FunT\",\n \"static\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"statics of function\"\n },\n \"kind\":\"AnyFunT\"\n },\n \"prototype\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"empty prototype object\"\n },\n \"kind\":\"MixedT\"\n },\n \"funType\":{\n \"thisType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"global object\"\n },\n \"kind\":\"MixedT\"\n },\n \"paramTypes\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"number\"\n },\n \"kind\":\"NumT\"\n }\n ],\n \"paramNames\":[\"x\"],\n \"returnType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n \"closureIndex\":0,\n \"changeset\":{\"vars\":[],\"refis\":[]}\n }\n}","type":"(x: number) => void","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":3,"column":10,"offset":49},"end":{"line":3,"column":12,"offset":52}},"path":"test.js","line":3,"endline":3,"start":10,"end":12},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"number\"\n },\n \"kind\":\"NumT\"\n}","type":"number","reasons":[{"desc":"number","loc":{"source":"test.js","type":"SourceFile","start":{"line":4,"column":5,"offset":64},"end":{"line":4,"column":5,"offset":65}},"path":"test.js","line":4,"endline":4,"start":5,"end":5}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":3,"column":14,"offset":53},"end":{"line":3,"column":14,"offset":54}},"path":"test.js","line":3,"endline":3,"start":14,"end":14},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"function\"\n },\n \"kind\":\"FunT\",\n \"static\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"statics of function\"\n },\n \"kind\":\"AnyFunT\"\n },\n \"prototype\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"empty prototype object\"\n },\n \"kind\":\"MixedT\"\n },\n \"funType\":{\n \"thisType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"global object\"\n },\n \"kind\":\"MixedT\"\n },\n \"paramTypes\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"number\"\n },\n \"kind\":\"NumT\"\n }\n ],\n \"paramNames\":[\"x\"],\n \"returnType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n \"closureIndex\":0,\n \"changeset\":{\"vars\":[],\"refis\":[]}\n }\n}","type":"(x: number) => void","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":4,"column":1,"offset":60},"end":{"line":4,"column":3,"offset":63}},"path":"test.js","line":4,"endline":4,"start":1,"end":3},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n}","type":"void","reasons":[{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":4,"column":1,"offset":60},"end":{"line":4,"column":6,"offset":66}},"path":"test.js","line":4,"endline":4,"start":1,"end":6}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":4,"column":1,"offset":60},"end":{"line":4,"column":6,"offset":66}},"path":"test.js","line":4,"endline":4,"start":1,"end":6},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"number\"\n },\n \"kind\":\"NumT\"\n}","type":"number","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":4,"column":5,"offset":64},"end":{"line":4,"column":5,"offset":65}},"path":"test.js","line":4,"endline":4,"start":5,"end":5},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n}","type":"string","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":5,"column":5,"offset":72},"end":{"line":5,"column":12,"offset":80}},"path":"test.js","line":5,"endline":5,"start":5,"end":12},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"number\"\n },\n \"kind\":\"NumT\"\n}","type":"number","reasons":[{"desc":"number","loc":{"source":"test.js","type":"SourceFile","start":{"line":5,"column":16,"offset":83},"end":{"line":5,"column":18,"offset":86}},"path":"test.js","line":5,"endline":5,"start":16,"end":18}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":5,"column":16,"offset":83},"end":{"line":5,"column":18,"offset":86}},"path":"test.js","line":5,"endline":5,"start":16,"end":18},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"function\"\n },\n \"kind\":\"FunT\",\n \"static\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"statics of function\"\n },\n \"kind\":\"AnyFunT\"\n },\n \"prototype\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"empty prototype object\"\n },\n \"kind\":\"MixedT\"\n },\n \"funType\":{\n \"thisType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"global object\"\n },\n \"kind\":\"MixedT\"\n },\n \"paramTypes\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"\"\n },\n \"kind\":\"EmptyT\"\n }\n ],\n \"paramNames\":[\"x\"],\n \"returnType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"\"\n },\n \"kind\":\"EmptyT\"\n },\n \"closureIndex\":0,\n \"changeset\":{\"vars\":[],\"refis\":[]}\n }\n}","type":"(x: ) => ","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":7,"column":10,"offset":98},"end":{"line":7,"column":20,"offset":109}},"path":"test.js","line":7,"endline":7,"start":10,"end":20},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"\"\n },\n \"kind\":\"EmptyT\"\n}","type":"","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":7,"column":22,"offset":110},"end":{"line":7,"column":22,"offset":111}},"path":"test.js","line":7,"endline":7,"start":22,"end":22},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"\"\n },\n \"kind\":\"EmptyT\"\n}","type":"","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":8,"column":10,"offset":124},"end":{"line":8,"column":10,"offset":125}},"path":"test.js","line":8,"endline":8,"start":10,"end":10},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"function\"\n },\n \"kind\":\"FunT\",\n \"static\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"statics of function\"\n },\n \"kind\":\"AnyFunT\"\n },\n \"prototype\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"empty prototype object\"\n },\n \"kind\":\"MixedT\"\n },\n \"funType\":{\n \"thisType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"global object\"\n },\n \"kind\":\"MixedT\"\n },\n \"paramTypes\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n }\n ],\n \"paramNames\":[\"val\"],\n \"returnType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n },\n \"closureIndex\":0,\n \"changeset\":{\"vars\":[],\"refis\":[]}\n }\n}","type":"(val: string | null | void | Object) => string | void | Object","reasons":[{"desc":"arrow function","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":25,"offset":189},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":25,"end":61}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":7,"offset":171},"end":{"line":12,"column":21,"offset":186}},"path":"test.js","line":12,"endline":12,"start":7,"end":21},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n}","type":"string | null | void | Object","reasons":[{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":50,"offset":333},"end":{"line":15,"column":50,"offset":334}},"path":"test.js","line":15,"endline":15,"start":50,"end":50},{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":50,"offset":278},"end":{"line":14,"column":50,"offset":279}},"path":"test.js","line":14,"endline":14,"start":50,"end":50},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":50,"offset":443},"end":{"line":17,"column":50,"offset":444}},"path":"test.js","line":17,"endline":17,"start":50,"end":50},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":50,"offset":388},"end":{"line":16,"column":50,"offset":389}},"path":"test.js","line":16,"endline":16,"start":50,"end":50},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":50,"offset":333},"end":{"line":15,"column":50,"offset":334}},"path":"test.js","line":15,"endline":15,"start":50,"end":50},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":50,"offset":278},"end":{"line":14,"column":50,"offset":279}},"path":"test.js","line":14,"endline":14,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":50,"offset":443},"end":{"line":17,"column":50,"offset":444}},"path":"test.js","line":17,"endline":17,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":50,"offset":388},"end":{"line":16,"column":50,"offset":389}},"path":"test.js","line":16,"endline":16,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":50,"offset":333},"end":{"line":15,"column":50,"offset":334}},"path":"test.js","line":15,"endline":15,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":50,"offset":278},"end":{"line":14,"column":50,"offset":279}},"path":"test.js","line":14,"endline":14,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":50,"offset":443},"end":{"line":17,"column":50,"offset":444}},"path":"test.js","line":17,"endline":17,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":50,"offset":388},"end":{"line":16,"column":50,"offset":389}},"path":"test.js","line":16,"endline":16,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":50,"offset":333},"end":{"line":15,"column":50,"offset":334}},"path":"test.js","line":15,"endline":15,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":50,"offset":278},"end":{"line":14,"column":50,"offset":279}},"path":"test.js","line":14,"endline":14,"start":50,"end":50},{"desc":"","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":50,"offset":443},"end":{"line":17,"column":50,"offset":444}},"path":"test.js","line":17,"endline":17,"start":50,"end":50},{"desc":"","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":50,"offset":388},"end":{"line":16,"column":50,"offset":389}},"path":"test.js","line":16,"endline":16,"start":50,"end":50},{"desc":"","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":50,"offset":333},"end":{"line":15,"column":50,"offset":334}},"path":"test.js","line":15,"endline":15,"start":50,"end":50},{"desc":"","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":50,"offset":278},"end":{"line":14,"column":50,"offset":279}},"path":"test.js","line":14,"endline":14,"start":50,"end":50},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":50,"offset":443},"end":{"line":17,"column":50,"offset":444}},"path":"test.js","line":17,"endline":17,"start":50,"end":50},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":50,"offset":388},"end":{"line":16,"column":50,"offset":389}},"path":"test.js","line":16,"endline":16,"start":50,"end":50}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":25,"offset":189},"end":{"line":12,"column":27,"offset":192}},"path":"test.js","line":12,"endline":12,"start":25,"end":27},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"function\"\n },\n \"kind\":\"FunT\",\n \"static\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"statics of function\"\n },\n \"kind\":\"AnyFunT\"\n },\n \"prototype\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"empty prototype object\"\n },\n \"kind\":\"MixedT\"\n },\n \"funType\":{\n \"thisType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"global object\"\n },\n \"kind\":\"MixedT\"\n },\n \"paramTypes\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n }\n ],\n \"paramNames\":[\"val\"],\n \"returnType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n },\n \"closureIndex\":0,\n \"changeset\":{\"vars\":[],\"refis\":[]}\n }\n}","type":"(val: string | null | void | Object) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":25,"offset":189},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":25,"end":61},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n}","type":"string | null | void | Object","reasons":[{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":34,"offset":199}},"path":"test.js","line":12,"endline":12,"start":32,"end":34},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":34,"offset":199}},"path":"test.js","line":12,"endline":12,"start":32,"end":34},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":34,"offset":199}},"path":"test.js","line":12,"endline":12,"start":32,"end":34},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":34,"offset":199}},"path":"test.js","line":12,"endline":12,"start":32,"end":34},{"desc":"","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":34,"offset":199}},"path":"test.js","line":12,"endline":12,"start":32,"end":34},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":34,"offset":199}},"path":"test.js","line":12,"endline":12,"start":32,"end":34}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":34,"offset":199}},"path":"test.js","line":12,"endline":12,"start":32,"end":34},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n}","type":"string | void | Object","reasons":[{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":59,"offset":223},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":59,"end":61},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":59,"offset":223},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":59,"end":61},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":47,"offset":211},"end":{"line":12,"column":55,"offset":220}},"path":"test.js","line":12,"endline":12,"start":47,"end":55},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":59,"offset":223},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":59,"end":61},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":59,"offset":223},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":59,"end":61}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":32,"end":61},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n}","type":"null","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":40,"offset":204},"end":{"line":12,"column":43,"offset":208}},"path":"test.js","line":12,"endline":12,"start":40,"end":43},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n}","type":"void","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":47,"offset":211},"end":{"line":12,"column":55,"offset":220}},"path":"test.js","line":12,"endline":12,"start":47,"end":55},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n}","type":"string | void | Object","reasons":[{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":59,"offset":223},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":59,"end":61},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":59,"offset":223},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":59,"end":61},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":59,"offset":223},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":59,"end":61},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":59,"offset":223},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":59,"end":61}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":59,"offset":223},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":59,"end":61},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"function\"\n },\n \"kind\":\"FunT\",\n \"static\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"statics of function\"\n },\n \"kind\":\"AnyFunT\"\n },\n \"prototype\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"empty prototype object\"\n },\n \"kind\":\"MixedT\"\n },\n \"funType\":{\n \"thisType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"global object\"\n },\n \"kind\":\"MixedT\"\n },\n \"paramTypes\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"?any object\"\n },\n \"kind\":\"MaybeT\",\n \"type\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n }\n ],\n \"paramNames\":[\"x\"],\n \"returnType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n },\n \"closureIndex\":0,\n \"changeset\":{\"vars\":[],\"refis\":[]}\n }\n}","type":"(x: ?Object) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":10,"offset":238},"end":{"line":14,"column":11,"offset":240}},"path":"test.js","line":14,"endline":14,"start":10,"end":11},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"?any object\"\n },\n \"kind\":\"MaybeT\",\n \"type\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n}","type":"?Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":13,"offset":241},"end":{"line":14,"column":22,"offset":251}},"path":"test.js","line":14,"endline":14,"start":13,"end":22},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"function\"\n },\n \"kind\":\"FunT\",\n \"static\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"statics of function\"\n },\n \"kind\":\"AnyFunT\"\n },\n \"prototype\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"empty prototype object\"\n },\n \"kind\":\"MixedT\"\n },\n \"funType\":{\n \"thisType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"global object\"\n },\n \"kind\":\"MixedT\"\n },\n \"paramTypes\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n }\n ],\n \"paramNames\":[\"val\"],\n \"returnType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n },\n \"closureIndex\":0,\n \"changeset\":{\"vars\":[],\"refis\":[]}\n }\n}","type":"(val: string | null | void | Object) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":34,"offset":262},"end":{"line":14,"column":48,"offset":277}},"path":"test.js","line":14,"endline":14,"start":34,"end":48},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n}","type":"string | void | Object","reasons":[{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":34,"offset":262},"end":{"line":14,"column":51,"offset":280}},"path":"test.js","line":14,"endline":14,"start":34,"end":51},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":34,"offset":262},"end":{"line":14,"column":51,"offset":280}},"path":"test.js","line":14,"endline":14,"start":34,"end":51},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":34,"offset":262},"end":{"line":14,"column":51,"offset":280}},"path":"test.js","line":14,"endline":14,"start":34,"end":51},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":34,"offset":262},"end":{"line":14,"column":51,"offset":280}},"path":"test.js","line":14,"endline":14,"start":34,"end":51}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":34,"offset":262},"end":{"line":14,"column":51,"offset":280}},"path":"test.js","line":14,"endline":14,"start":34,"end":51},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"?any object\"\n },\n \"kind\":\"MaybeT\",\n \"type\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n}","type":"?Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":50,"offset":278},"end":{"line":14,"column":50,"offset":279}},"path":"test.js","line":14,"endline":14,"start":50,"end":50},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"function\"\n },\n \"kind\":\"FunT\",\n \"static\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"statics of function\"\n },\n \"kind\":\"AnyFunT\"\n },\n \"prototype\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"empty prototype object\"\n },\n \"kind\":\"MixedT\"\n },\n \"funType\":{\n \"thisType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"global object\"\n },\n \"kind\":\"MixedT\"\n },\n \"paramTypes\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"?any object\"\n },\n \"kind\":\"MaybeT\",\n \"type\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n }\n ],\n \"paramNames\":[\"x\"],\n \"returnType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n },\n \"closureIndex\":0,\n \"changeset\":{\"vars\":[],\"refis\":[]}\n }\n}","type":"(x: ?Object) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":10,"offset":293},"end":{"line":15,"column":11,"offset":295}},"path":"test.js","line":15,"endline":15,"start":10,"end":11},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"?any object\"\n },\n \"kind\":\"MaybeT\",\n \"type\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n}","type":"?Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":13,"offset":296},"end":{"line":15,"column":22,"offset":306}},"path":"test.js","line":15,"endline":15,"start":13,"end":22},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"function\"\n },\n \"kind\":\"FunT\",\n \"static\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"statics of function\"\n },\n \"kind\":\"AnyFunT\"\n },\n \"prototype\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"empty prototype object\"\n },\n \"kind\":\"MixedT\"\n },\n \"funType\":{\n \"thisType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"global object\"\n },\n \"kind\":\"MixedT\"\n },\n \"paramTypes\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n }\n ],\n \"paramNames\":[\"val\"],\n \"returnType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n },\n \"closureIndex\":0,\n \"changeset\":{\"vars\":[],\"refis\":[]}\n }\n}","type":"(val: string | null | void | Object) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":34,"offset":317},"end":{"line":15,"column":48,"offset":332}},"path":"test.js","line":15,"endline":15,"start":34,"end":48},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n}","type":"string | void | Object","reasons":[{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":34,"offset":317},"end":{"line":15,"column":51,"offset":335}},"path":"test.js","line":15,"endline":15,"start":34,"end":51},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":34,"offset":317},"end":{"line":15,"column":51,"offset":335}},"path":"test.js","line":15,"endline":15,"start":34,"end":51},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":34,"offset":317},"end":{"line":15,"column":51,"offset":335}},"path":"test.js","line":15,"endline":15,"start":34,"end":51},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":34,"offset":317},"end":{"line":15,"column":51,"offset":335}},"path":"test.js","line":15,"endline":15,"start":34,"end":51}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":34,"offset":317},"end":{"line":15,"column":51,"offset":335}},"path":"test.js","line":15,"endline":15,"start":34,"end":51},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"?any object\"\n },\n \"kind\":\"MaybeT\",\n \"type\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n}","type":"?Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":50,"offset":333},"end":{"line":15,"column":50,"offset":334}},"path":"test.js","line":15,"endline":15,"start":50,"end":50},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"function\"\n },\n \"kind\":\"FunT\",\n \"static\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"statics of function\"\n },\n \"kind\":\"AnyFunT\"\n },\n \"prototype\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"empty prototype object\"\n },\n \"kind\":\"MixedT\"\n },\n \"funType\":{\n \"thisType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"global object\"\n },\n \"kind\":\"MixedT\"\n },\n \"paramTypes\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"?string\"\n },\n \"kind\":\"MaybeT\",\n \"type\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n }\n }\n ],\n \"paramNames\":[\"x\"],\n \"returnType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n },\n \"closureIndex\":0,\n \"changeset\":{\"vars\":[],\"refis\":[]}\n }\n}","type":"(x: ?string) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":10,"offset":348},"end":{"line":16,"column":11,"offset":350}},"path":"test.js","line":16,"endline":16,"start":10,"end":11},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"?string\"\n },\n \"kind\":\"MaybeT\",\n \"type\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n }\n}","type":"?string","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":13,"offset":351},"end":{"line":16,"column":22,"offset":361}},"path":"test.js","line":16,"endline":16,"start":13,"end":22},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"function\"\n },\n \"kind\":\"FunT\",\n \"static\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"statics of function\"\n },\n \"kind\":\"AnyFunT\"\n },\n \"prototype\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"empty prototype object\"\n },\n \"kind\":\"MixedT\"\n },\n \"funType\":{\n \"thisType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"global object\"\n },\n \"kind\":\"MixedT\"\n },\n \"paramTypes\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n }\n ],\n \"paramNames\":[\"val\"],\n \"returnType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n },\n \"closureIndex\":0,\n \"changeset\":{\"vars\":[],\"refis\":[]}\n }\n}","type":"(val: string | null | void | Object) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":34,"offset":372},"end":{"line":16,"column":48,"offset":387}},"path":"test.js","line":16,"endline":16,"start":34,"end":48},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n}","type":"string | void | Object","reasons":[{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":34,"offset":372},"end":{"line":16,"column":51,"offset":390}},"path":"test.js","line":16,"endline":16,"start":34,"end":51},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":34,"offset":372},"end":{"line":16,"column":51,"offset":390}},"path":"test.js","line":16,"endline":16,"start":34,"end":51},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":34,"offset":372},"end":{"line":16,"column":51,"offset":390}},"path":"test.js","line":16,"endline":16,"start":34,"end":51},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":34,"offset":372},"end":{"line":16,"column":51,"offset":390}},"path":"test.js","line":16,"endline":16,"start":34,"end":51}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":34,"offset":372},"end":{"line":16,"column":51,"offset":390}},"path":"test.js","line":16,"endline":16,"start":34,"end":51},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"?string\"\n },\n \"kind\":\"MaybeT\",\n \"type\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n }\n}","type":"?string","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":50,"offset":388},"end":{"line":16,"column":50,"offset":389}},"path":"test.js","line":16,"endline":16,"start":50,"end":50},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"function\"\n },\n \"kind\":\"FunT\",\n \"static\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"statics of function\"\n },\n \"kind\":\"AnyFunT\"\n },\n \"prototype\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"empty prototype object\"\n },\n \"kind\":\"MixedT\"\n },\n \"funType\":{\n \"thisType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"global object\"\n },\n \"kind\":\"MixedT\"\n },\n \"paramTypes\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"?string\"\n },\n \"kind\":\"MaybeT\",\n \"type\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n }\n }\n ],\n \"paramNames\":[\"x\"],\n \"returnType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n },\n \"closureIndex\":0,\n \"changeset\":{\"vars\":[],\"refis\":[]}\n }\n}","type":"(x: ?string) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":10,"offset":403},"end":{"line":17,"column":11,"offset":405}},"path":"test.js","line":17,"endline":17,"start":10,"end":11},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"?string\"\n },\n \"kind\":\"MaybeT\",\n \"type\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n }\n}","type":"?string","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":13,"offset":406},"end":{"line":17,"column":22,"offset":416}},"path":"test.js","line":17,"endline":17,"start":13,"end":22},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"function\"\n },\n \"kind\":\"FunT\",\n \"static\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"statics of function\"\n },\n \"kind\":\"AnyFunT\"\n },\n \"prototype\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"empty prototype object\"\n },\n \"kind\":\"MixedT\"\n },\n \"funType\":{\n \"thisType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"global object\"\n },\n \"kind\":\"MixedT\"\n },\n \"paramTypes\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n }\n ],\n \"paramNames\":[\"val\"],\n \"returnType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n },\n \"closureIndex\":0,\n \"changeset\":{\"vars\":[],\"refis\":[]}\n }\n}","type":"(val: string | null | void | Object) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":34,"offset":427},"end":{"line":17,"column":48,"offset":442}},"path":"test.js","line":17,"endline":17,"start":34,"end":48},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n}","type":"string | void | Object","reasons":[{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":34,"offset":427},"end":{"line":17,"column":51,"offset":445}},"path":"test.js","line":17,"endline":17,"start":34,"end":51},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":34,"offset":427},"end":{"line":17,"column":51,"offset":445}},"path":"test.js","line":17,"endline":17,"start":34,"end":51},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":34,"offset":427},"end":{"line":17,"column":51,"offset":445}},"path":"test.js","line":17,"endline":17,"start":34,"end":51},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":34,"offset":427},"end":{"line":17,"column":51,"offset":445}},"path":"test.js","line":17,"endline":17,"start":34,"end":51}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":34,"offset":427},"end":{"line":17,"column":51,"offset":445}},"path":"test.js","line":17,"endline":17,"start":34,"end":51},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"?string\"\n },\n \"kind\":\"MaybeT\",\n \"type\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n }\n}","type":"?string","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":50,"offset":443},"end":{"line":17,"column":50,"offset":444}},"path":"test.js","line":17,"endline":17,"start":50,"end":50}] +[{"type":"number","reasons":[{"desc":"number","loc":{"source":"test.js","type":"SourceFile","start":{"line":2,"column":11,"offset":19},"end":{"line":2,"column":29,"offset":38}},"path":"test.js","line":2,"endline":2,"start":11,"end":29}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":2,"column":5,"offset":13},"end":{"line":2,"column":7,"offset":16}},"path":"test.js","line":2,"endline":2,"start":5,"end":7},{"type":"number","reasons":[{"desc":"number","loc":{"source":"test.js","type":"SourceFile","start":{"line":2,"column":11,"offset":19},"end":{"line":2,"column":29,"offset":38}},"path":"test.js","line":2,"endline":2,"start":11,"end":29}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":2,"column":11,"offset":19},"end":{"line":2,"column":29,"offset":38}},"path":"test.js","line":2,"endline":2,"start":11,"end":29},{"type":"(x: number) => void","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":3,"column":10,"offset":49},"end":{"line":3,"column":12,"offset":52}},"path":"test.js","line":3,"endline":3,"start":10,"end":12},{"type":"number","reasons":[{"desc":"number","loc":{"source":"test.js","type":"SourceFile","start":{"line":4,"column":5,"offset":64},"end":{"line":4,"column":5,"offset":65}},"path":"test.js","line":4,"endline":4,"start":5,"end":5}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":3,"column":14,"offset":53},"end":{"line":3,"column":14,"offset":54}},"path":"test.js","line":3,"endline":3,"start":14,"end":14},{"type":"(x: number) => void","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":4,"column":1,"offset":60},"end":{"line":4,"column":3,"offset":63}},"path":"test.js","line":4,"endline":4,"start":1,"end":3},{"type":"void","reasons":[{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":4,"column":1,"offset":60},"end":{"line":4,"column":6,"offset":66}},"path":"test.js","line":4,"endline":4,"start":1,"end":6}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":4,"column":1,"offset":60},"end":{"line":4,"column":6,"offset":66}},"path":"test.js","line":4,"endline":4,"start":1,"end":6},{"type":"number","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":4,"column":5,"offset":64},"end":{"line":4,"column":5,"offset":65}},"path":"test.js","line":4,"endline":4,"start":5,"end":5},{"type":"string","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":5,"column":5,"offset":72},"end":{"line":5,"column":12,"offset":80}},"path":"test.js","line":5,"endline":5,"start":5,"end":12},{"type":"number","reasons":[{"desc":"number","loc":{"source":"test.js","type":"SourceFile","start":{"line":5,"column":16,"offset":83},"end":{"line":5,"column":18,"offset":86}},"path":"test.js","line":5,"endline":5,"start":16,"end":18}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":5,"column":16,"offset":83},"end":{"line":5,"column":18,"offset":86}},"path":"test.js","line":5,"endline":5,"start":16,"end":18},{"type":"(x: ) => ","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":7,"column":10,"offset":98},"end":{"line":7,"column":20,"offset":109}},"path":"test.js","line":7,"endline":7,"start":10,"end":20},{"type":"","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":7,"column":22,"offset":110},"end":{"line":7,"column":22,"offset":111}},"path":"test.js","line":7,"endline":7,"start":22,"end":22},{"type":"","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":8,"column":10,"offset":124},"end":{"line":8,"column":10,"offset":125}},"path":"test.js","line":8,"endline":8,"start":10,"end":10},{"type":"(val: string | null | void | Object) => string | void | Object","reasons":[{"desc":"arrow function","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":25,"offset":189},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":25,"end":61}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":7,"offset":171},"end":{"line":12,"column":21,"offset":186}},"path":"test.js","line":12,"endline":12,"start":7,"end":21},{"type":"string | null | void | Object","reasons":[{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":50,"offset":333},"end":{"line":15,"column":50,"offset":334}},"path":"test.js","line":15,"endline":15,"start":50,"end":50},{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":50,"offset":278},"end":{"line":14,"column":50,"offset":279}},"path":"test.js","line":14,"endline":14,"start":50,"end":50},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":50,"offset":443},"end":{"line":17,"column":50,"offset":444}},"path":"test.js","line":17,"endline":17,"start":50,"end":50},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":50,"offset":388},"end":{"line":16,"column":50,"offset":389}},"path":"test.js","line":16,"endline":16,"start":50,"end":50},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":50,"offset":333},"end":{"line":15,"column":50,"offset":334}},"path":"test.js","line":15,"endline":15,"start":50,"end":50},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":50,"offset":278},"end":{"line":14,"column":50,"offset":279}},"path":"test.js","line":14,"endline":14,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":50,"offset":443},"end":{"line":17,"column":50,"offset":444}},"path":"test.js","line":17,"endline":17,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":50,"offset":388},"end":{"line":16,"column":50,"offset":389}},"path":"test.js","line":16,"endline":16,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":50,"offset":333},"end":{"line":15,"column":50,"offset":334}},"path":"test.js","line":15,"endline":15,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":50,"offset":278},"end":{"line":14,"column":50,"offset":279}},"path":"test.js","line":14,"endline":14,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":50,"offset":443},"end":{"line":17,"column":50,"offset":444}},"path":"test.js","line":17,"endline":17,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":50,"offset":388},"end":{"line":16,"column":50,"offset":389}},"path":"test.js","line":16,"endline":16,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":50,"offset":333},"end":{"line":15,"column":50,"offset":334}},"path":"test.js","line":15,"endline":15,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":50,"offset":278},"end":{"line":14,"column":50,"offset":279}},"path":"test.js","line":14,"endline":14,"start":50,"end":50},{"desc":"","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":50,"offset":443},"end":{"line":17,"column":50,"offset":444}},"path":"test.js","line":17,"endline":17,"start":50,"end":50},{"desc":"","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":50,"offset":388},"end":{"line":16,"column":50,"offset":389}},"path":"test.js","line":16,"endline":16,"start":50,"end":50},{"desc":"","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":50,"offset":333},"end":{"line":15,"column":50,"offset":334}},"path":"test.js","line":15,"endline":15,"start":50,"end":50},{"desc":"","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":50,"offset":278},"end":{"line":14,"column":50,"offset":279}},"path":"test.js","line":14,"endline":14,"start":50,"end":50},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":50,"offset":443},"end":{"line":17,"column":50,"offset":444}},"path":"test.js","line":17,"endline":17,"start":50,"end":50},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":50,"offset":388},"end":{"line":16,"column":50,"offset":389}},"path":"test.js","line":16,"endline":16,"start":50,"end":50}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":25,"offset":189},"end":{"line":12,"column":27,"offset":192}},"path":"test.js","line":12,"endline":12,"start":25,"end":27},{"type":"(val: string | null | void | Object) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":25,"offset":189},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":25,"end":61},{"type":"string | null | void | Object","reasons":[{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":34,"offset":199}},"path":"test.js","line":12,"endline":12,"start":32,"end":34},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":34,"offset":199}},"path":"test.js","line":12,"endline":12,"start":32,"end":34},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":34,"offset":199}},"path":"test.js","line":12,"endline":12,"start":32,"end":34},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":34,"offset":199}},"path":"test.js","line":12,"endline":12,"start":32,"end":34},{"desc":"","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":34,"offset":199}},"path":"test.js","line":12,"endline":12,"start":32,"end":34},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":34,"offset":199}},"path":"test.js","line":12,"endline":12,"start":32,"end":34}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":34,"offset":199}},"path":"test.js","line":12,"endline":12,"start":32,"end":34},{"type":"string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":32,"end":61},{"type":"null","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":40,"offset":204},"end":{"line":12,"column":43,"offset":208}},"path":"test.js","line":12,"endline":12,"start":40,"end":43},{"type":"void","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":47,"offset":211},"end":{"line":12,"column":55,"offset":220}},"path":"test.js","line":12,"endline":12,"start":47,"end":55},{"type":"string | void | Object","reasons":[{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":59,"offset":223},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":59,"end":61},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":59,"offset":223},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":59,"end":61},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":59,"offset":223},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":59,"end":61},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":59,"offset":223},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":59,"end":61}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":59,"offset":223},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":59,"end":61},{"type":"(x: ?Object) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":10,"offset":238},"end":{"line":14,"column":11,"offset":240}},"path":"test.js","line":14,"endline":14,"start":10,"end":11},{"type":"?Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":13,"offset":241},"end":{"line":14,"column":22,"offset":251}},"path":"test.js","line":14,"endline":14,"start":13,"end":22},{"type":"(val: string | null | void | Object) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":34,"offset":262},"end":{"line":14,"column":48,"offset":277}},"path":"test.js","line":14,"endline":14,"start":34,"end":48},{"type":"string | void | Object","reasons":[{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":34,"offset":262},"end":{"line":14,"column":51,"offset":280}},"path":"test.js","line":14,"endline":14,"start":34,"end":51},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":34,"offset":262},"end":{"line":14,"column":51,"offset":280}},"path":"test.js","line":14,"endline":14,"start":34,"end":51},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":34,"offset":262},"end":{"line":14,"column":51,"offset":280}},"path":"test.js","line":14,"endline":14,"start":34,"end":51},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":34,"offset":262},"end":{"line":14,"column":51,"offset":280}},"path":"test.js","line":14,"endline":14,"start":34,"end":51}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":34,"offset":262},"end":{"line":14,"column":51,"offset":280}},"path":"test.js","line":14,"endline":14,"start":34,"end":51},{"type":"?Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":50,"offset":278},"end":{"line":14,"column":50,"offset":279}},"path":"test.js","line":14,"endline":14,"start":50,"end":50},{"type":"(x: ?Object) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":10,"offset":293},"end":{"line":15,"column":11,"offset":295}},"path":"test.js","line":15,"endline":15,"start":10,"end":11},{"type":"?Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":13,"offset":296},"end":{"line":15,"column":22,"offset":306}},"path":"test.js","line":15,"endline":15,"start":13,"end":22},{"type":"(val: string | null | void | Object) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":34,"offset":317},"end":{"line":15,"column":48,"offset":332}},"path":"test.js","line":15,"endline":15,"start":34,"end":48},{"type":"string | void | Object","reasons":[{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":34,"offset":317},"end":{"line":15,"column":51,"offset":335}},"path":"test.js","line":15,"endline":15,"start":34,"end":51},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":34,"offset":317},"end":{"line":15,"column":51,"offset":335}},"path":"test.js","line":15,"endline":15,"start":34,"end":51},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":34,"offset":317},"end":{"line":15,"column":51,"offset":335}},"path":"test.js","line":15,"endline":15,"start":34,"end":51},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":34,"offset":317},"end":{"line":15,"column":51,"offset":335}},"path":"test.js","line":15,"endline":15,"start":34,"end":51}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":34,"offset":317},"end":{"line":15,"column":51,"offset":335}},"path":"test.js","line":15,"endline":15,"start":34,"end":51},{"type":"?Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":50,"offset":333},"end":{"line":15,"column":50,"offset":334}},"path":"test.js","line":15,"endline":15,"start":50,"end":50},{"type":"(x: ?string) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":10,"offset":348},"end":{"line":16,"column":11,"offset":350}},"path":"test.js","line":16,"endline":16,"start":10,"end":11},{"type":"?string","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":13,"offset":351},"end":{"line":16,"column":22,"offset":361}},"path":"test.js","line":16,"endline":16,"start":13,"end":22},{"type":"(val: string | null | void | Object) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":34,"offset":372},"end":{"line":16,"column":48,"offset":387}},"path":"test.js","line":16,"endline":16,"start":34,"end":48},{"type":"string | void | Object","reasons":[{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":34,"offset":372},"end":{"line":16,"column":51,"offset":390}},"path":"test.js","line":16,"endline":16,"start":34,"end":51},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":34,"offset":372},"end":{"line":16,"column":51,"offset":390}},"path":"test.js","line":16,"endline":16,"start":34,"end":51},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":34,"offset":372},"end":{"line":16,"column":51,"offset":390}},"path":"test.js","line":16,"endline":16,"start":34,"end":51},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":34,"offset":372},"end":{"line":16,"column":51,"offset":390}},"path":"test.js","line":16,"endline":16,"start":34,"end":51}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":34,"offset":372},"end":{"line":16,"column":51,"offset":390}},"path":"test.js","line":16,"endline":16,"start":34,"end":51},{"type":"?string","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":50,"offset":388},"end":{"line":16,"column":50,"offset":389}},"path":"test.js","line":16,"endline":16,"start":50,"end":50},{"type":"(x: ?string) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":10,"offset":403},"end":{"line":17,"column":11,"offset":405}},"path":"test.js","line":17,"endline":17,"start":10,"end":11},{"type":"?string","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":13,"offset":406},"end":{"line":17,"column":22,"offset":416}},"path":"test.js","line":17,"endline":17,"start":13,"end":22},{"type":"(val: string | null | void | Object) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":34,"offset":427},"end":{"line":17,"column":48,"offset":442}},"path":"test.js","line":17,"endline":17,"start":34,"end":48},{"type":"string | void | Object","reasons":[{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":34,"offset":427},"end":{"line":17,"column":51,"offset":445}},"path":"test.js","line":17,"endline":17,"start":34,"end":51},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":34,"offset":427},"end":{"line":17,"column":51,"offset":445}},"path":"test.js","line":17,"endline":17,"start":34,"end":51},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":34,"offset":427},"end":{"line":17,"column":51,"offset":445}},"path":"test.js","line":17,"endline":17,"start":34,"end":51},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":34,"offset":427},"end":{"line":17,"column":51,"offset":445}},"path":"test.js","line":17,"endline":17,"start":34,"end":51}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":34,"offset":427},"end":{"line":17,"column":51,"offset":445}},"path":"test.js","line":17,"endline":17,"start":34,"end":51},{"type":"?string","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":50,"offset":443},"end":{"line":17,"column":50,"offset":444}},"path":"test.js","line":17,"endline":17,"start":50,"end":50}] +[{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"number\"\n },\n \"kind\":\"NumT\"\n}","type":"number","reasons":[{"desc":"number","loc":{"source":"test.js","type":"SourceFile","start":{"line":2,"column":11,"offset":19},"end":{"line":2,"column":29,"offset":38}},"path":"test.js","line":2,"endline":2,"start":11,"end":29}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":2,"column":5,"offset":13},"end":{"line":2,"column":7,"offset":16}},"path":"test.js","line":2,"endline":2,"start":5,"end":7},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"number\"\n },\n \"kind\":\"NumT\"\n}","type":"number","reasons":[{"desc":"number","loc":{"source":"test.js","type":"SourceFile","start":{"line":2,"column":11,"offset":19},"end":{"line":2,"column":29,"offset":38}},"path":"test.js","line":2,"endline":2,"start":11,"end":29}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":2,"column":11,"offset":19},"end":{"line":2,"column":29,"offset":38}},"path":"test.js","line":2,"endline":2,"start":11,"end":29},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"function\"\n },\n \"kind\":\"FunT\",\n \"static\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"statics of function\"\n },\n \"kind\":\"AnyFunT\"\n },\n \"prototype\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"empty prototype object\"\n },\n \"kind\":\"MixedT\"\n },\n \"funType\":{\n \"thisType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"global object\"\n },\n \"kind\":\"MixedT\"\n },\n \"paramTypes\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"number\"\n },\n \"kind\":\"NumT\"\n }\n ],\n \"paramNames\":[\"x\"],\n \"returnType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n \"closureIndex\":0,\n \"changeset\":{\"vars\":[],\"refis\":[]}\n }\n}","type":"(x: number) => void","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":3,"column":10,"offset":49},"end":{"line":3,"column":12,"offset":52}},"path":"test.js","line":3,"endline":3,"start":10,"end":12},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"number\"\n },\n \"kind\":\"NumT\"\n}","type":"number","reasons":[{"desc":"number","loc":{"source":"test.js","type":"SourceFile","start":{"line":4,"column":5,"offset":64},"end":{"line":4,"column":5,"offset":65}},"path":"test.js","line":4,"endline":4,"start":5,"end":5}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":3,"column":14,"offset":53},"end":{"line":3,"column":14,"offset":54}},"path":"test.js","line":3,"endline":3,"start":14,"end":14},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"function\"\n },\n \"kind\":\"FunT\",\n \"static\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"statics of function\"\n },\n \"kind\":\"AnyFunT\"\n },\n \"prototype\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"empty prototype object\"\n },\n \"kind\":\"MixedT\"\n },\n \"funType\":{\n \"thisType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"global object\"\n },\n \"kind\":\"MixedT\"\n },\n \"paramTypes\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"number\"\n },\n \"kind\":\"NumT\"\n }\n ],\n \"paramNames\":[\"x\"],\n \"returnType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n \"closureIndex\":0,\n \"changeset\":{\"vars\":[],\"refis\":[]}\n }\n}","type":"(x: number) => void","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":4,"column":1,"offset":60},"end":{"line":4,"column":3,"offset":63}},"path":"test.js","line":4,"endline":4,"start":1,"end":3},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n}","type":"void","reasons":[{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":4,"column":1,"offset":60},"end":{"line":4,"column":6,"offset":66}},"path":"test.js","line":4,"endline":4,"start":1,"end":6}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":4,"column":1,"offset":60},"end":{"line":4,"column":6,"offset":66}},"path":"test.js","line":4,"endline":4,"start":1,"end":6},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"number\"\n },\n \"kind\":\"NumT\"\n}","type":"number","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":4,"column":5,"offset":64},"end":{"line":4,"column":5,"offset":65}},"path":"test.js","line":4,"endline":4,"start":5,"end":5},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n}","type":"string","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":5,"column":5,"offset":72},"end":{"line":5,"column":12,"offset":80}},"path":"test.js","line":5,"endline":5,"start":5,"end":12},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"number\"\n },\n \"kind\":\"NumT\"\n}","type":"number","reasons":[{"desc":"number","loc":{"source":"test.js","type":"SourceFile","start":{"line":5,"column":16,"offset":83},"end":{"line":5,"column":18,"offset":86}},"path":"test.js","line":5,"endline":5,"start":16,"end":18}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":5,"column":16,"offset":83},"end":{"line":5,"column":18,"offset":86}},"path":"test.js","line":5,"endline":5,"start":16,"end":18},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"function\"\n },\n \"kind\":\"FunT\",\n \"static\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"statics of function\"\n },\n \"kind\":\"AnyFunT\"\n },\n \"prototype\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"empty prototype object\"\n },\n \"kind\":\"MixedT\"\n },\n \"funType\":{\n \"thisType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"global object\"\n },\n \"kind\":\"MixedT\"\n },\n \"paramTypes\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"\"\n },\n \"kind\":\"EmptyT\"\n }\n ],\n \"paramNames\":[\"x\"],\n \"returnType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"\"\n },\n \"kind\":\"EmptyT\"\n },\n \"closureIndex\":0,\n \"changeset\":{\"vars\":[],\"refis\":[]}\n }\n}","type":"(x: ) => ","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":7,"column":10,"offset":98},"end":{"line":7,"column":20,"offset":109}},"path":"test.js","line":7,"endline":7,"start":10,"end":20},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"\"\n },\n \"kind\":\"EmptyT\"\n}","type":"","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":7,"column":22,"offset":110},"end":{"line":7,"column":22,"offset":111}},"path":"test.js","line":7,"endline":7,"start":22,"end":22},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"\"\n },\n \"kind\":\"EmptyT\"\n}","type":"","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":8,"column":10,"offset":124},"end":{"line":8,"column":10,"offset":125}},"path":"test.js","line":8,"endline":8,"start":10,"end":10},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"function\"\n },\n \"kind\":\"FunT\",\n \"static\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"statics of function\"\n },\n \"kind\":\"AnyFunT\"\n },\n \"prototype\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"empty prototype object\"\n },\n \"kind\":\"MixedT\"\n },\n \"funType\":{\n \"thisType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"global object\"\n },\n \"kind\":\"MixedT\"\n },\n \"paramTypes\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n }\n ],\n \"paramNames\":[\"val\"],\n \"returnType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n },\n \"closureIndex\":0,\n \"changeset\":{\"vars\":[],\"refis\":[]}\n }\n}","type":"(val: string | null | void | Object) => string | void | Object","reasons":[{"desc":"arrow function","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":25,"offset":189},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":25,"end":61}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":7,"offset":171},"end":{"line":12,"column":21,"offset":186}},"path":"test.js","line":12,"endline":12,"start":7,"end":21},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n}","type":"string | null | void | Object","reasons":[{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":50,"offset":333},"end":{"line":15,"column":50,"offset":334}},"path":"test.js","line":15,"endline":15,"start":50,"end":50},{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":50,"offset":278},"end":{"line":14,"column":50,"offset":279}},"path":"test.js","line":14,"endline":14,"start":50,"end":50},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":50,"offset":443},"end":{"line":17,"column":50,"offset":444}},"path":"test.js","line":17,"endline":17,"start":50,"end":50},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":50,"offset":388},"end":{"line":16,"column":50,"offset":389}},"path":"test.js","line":16,"endline":16,"start":50,"end":50},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":50,"offset":333},"end":{"line":15,"column":50,"offset":334}},"path":"test.js","line":15,"endline":15,"start":50,"end":50},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":50,"offset":278},"end":{"line":14,"column":50,"offset":279}},"path":"test.js","line":14,"endline":14,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":50,"offset":443},"end":{"line":17,"column":50,"offset":444}},"path":"test.js","line":17,"endline":17,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":50,"offset":388},"end":{"line":16,"column":50,"offset":389}},"path":"test.js","line":16,"endline":16,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":50,"offset":333},"end":{"line":15,"column":50,"offset":334}},"path":"test.js","line":15,"endline":15,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":50,"offset":278},"end":{"line":14,"column":50,"offset":279}},"path":"test.js","line":14,"endline":14,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":50,"offset":443},"end":{"line":17,"column":50,"offset":444}},"path":"test.js","line":17,"endline":17,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":50,"offset":388},"end":{"line":16,"column":50,"offset":389}},"path":"test.js","line":16,"endline":16,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":50,"offset":333},"end":{"line":15,"column":50,"offset":334}},"path":"test.js","line":15,"endline":15,"start":50,"end":50},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":50,"offset":278},"end":{"line":14,"column":50,"offset":279}},"path":"test.js","line":14,"endline":14,"start":50,"end":50},{"desc":"","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":50,"offset":443},"end":{"line":17,"column":50,"offset":444}},"path":"test.js","line":17,"endline":17,"start":50,"end":50},{"desc":"","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":50,"offset":388},"end":{"line":16,"column":50,"offset":389}},"path":"test.js","line":16,"endline":16,"start":50,"end":50},{"desc":"","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":50,"offset":333},"end":{"line":15,"column":50,"offset":334}},"path":"test.js","line":15,"endline":15,"start":50,"end":50},{"desc":"","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":50,"offset":278},"end":{"line":14,"column":50,"offset":279}},"path":"test.js","line":14,"endline":14,"start":50,"end":50},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":50,"offset":443},"end":{"line":17,"column":50,"offset":444}},"path":"test.js","line":17,"endline":17,"start":50,"end":50},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":50,"offset":388},"end":{"line":16,"column":50,"offset":389}},"path":"test.js","line":16,"endline":16,"start":50,"end":50}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":25,"offset":189},"end":{"line":12,"column":27,"offset":192}},"path":"test.js","line":12,"endline":12,"start":25,"end":27},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"function\"\n },\n \"kind\":\"FunT\",\n \"static\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"statics of function\"\n },\n \"kind\":\"AnyFunT\"\n },\n \"prototype\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"empty prototype object\"\n },\n \"kind\":\"MixedT\"\n },\n \"funType\":{\n \"thisType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"global object\"\n },\n \"kind\":\"MixedT\"\n },\n \"paramTypes\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n }\n ],\n \"paramNames\":[\"val\"],\n \"returnType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n },\n \"closureIndex\":0,\n \"changeset\":{\"vars\":[],\"refis\":[]}\n }\n}","type":"(val: string | null | void | Object) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":25,"offset":189},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":25,"end":61},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n}","type":"string | null | void | Object","reasons":[{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":34,"offset":199}},"path":"test.js","line":12,"endline":12,"start":32,"end":34},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":34,"offset":199}},"path":"test.js","line":12,"endline":12,"start":32,"end":34},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":34,"offset":199}},"path":"test.js","line":12,"endline":12,"start":32,"end":34},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":34,"offset":199}},"path":"test.js","line":12,"endline":12,"start":32,"end":34},{"desc":"","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":34,"offset":199}},"path":"test.js","line":12,"endline":12,"start":32,"end":34},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":34,"offset":199}},"path":"test.js","line":12,"endline":12,"start":32,"end":34}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":34,"offset":199}},"path":"test.js","line":12,"endline":12,"start":32,"end":34},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n}","type":"string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":32,"offset":196},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":32,"end":61},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n}","type":"null","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":40,"offset":204},"end":{"line":12,"column":43,"offset":208}},"path":"test.js","line":12,"endline":12,"start":40,"end":43},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n}","type":"void","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":47,"offset":211},"end":{"line":12,"column":55,"offset":220}},"path":"test.js","line":12,"endline":12,"start":47,"end":55},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n}","type":"string | void | Object","reasons":[{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":59,"offset":223},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":59,"end":61},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":59,"offset":223},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":59,"end":61},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":59,"offset":223},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":59,"end":61},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":59,"offset":223},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":59,"end":61}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":12,"column":59,"offset":223},"end":{"line":12,"column":61,"offset":226}},"path":"test.js","line":12,"endline":12,"start":59,"end":61},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"function\"\n },\n \"kind\":\"FunT\",\n \"static\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"statics of function\"\n },\n \"kind\":\"AnyFunT\"\n },\n \"prototype\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"empty prototype object\"\n },\n \"kind\":\"MixedT\"\n },\n \"funType\":{\n \"thisType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"global object\"\n },\n \"kind\":\"MixedT\"\n },\n \"paramTypes\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"?any object\"\n },\n \"kind\":\"MaybeT\",\n \"type\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n }\n ],\n \"paramNames\":[\"x\"],\n \"returnType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n },\n \"closureIndex\":0,\n \"changeset\":{\"vars\":[],\"refis\":[]}\n }\n}","type":"(x: ?Object) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":10,"offset":238},"end":{"line":14,"column":11,"offset":240}},"path":"test.js","line":14,"endline":14,"start":10,"end":11},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"?any object\"\n },\n \"kind\":\"MaybeT\",\n \"type\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n}","type":"?Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":13,"offset":241},"end":{"line":14,"column":22,"offset":251}},"path":"test.js","line":14,"endline":14,"start":13,"end":22},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"function\"\n },\n \"kind\":\"FunT\",\n \"static\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"statics of function\"\n },\n \"kind\":\"AnyFunT\"\n },\n \"prototype\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"empty prototype object\"\n },\n \"kind\":\"MixedT\"\n },\n \"funType\":{\n \"thisType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"global object\"\n },\n \"kind\":\"MixedT\"\n },\n \"paramTypes\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n }\n ],\n \"paramNames\":[\"val\"],\n \"returnType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n },\n \"closureIndex\":0,\n \"changeset\":{\"vars\":[],\"refis\":[]}\n }\n}","type":"(val: string | null | void | Object) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":34,"offset":262},"end":{"line":14,"column":48,"offset":277}},"path":"test.js","line":14,"endline":14,"start":34,"end":48},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n}","type":"string | void | Object","reasons":[{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":34,"offset":262},"end":{"line":14,"column":51,"offset":280}},"path":"test.js","line":14,"endline":14,"start":34,"end":51},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":34,"offset":262},"end":{"line":14,"column":51,"offset":280}},"path":"test.js","line":14,"endline":14,"start":34,"end":51},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":34,"offset":262},"end":{"line":14,"column":51,"offset":280}},"path":"test.js","line":14,"endline":14,"start":34,"end":51},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":34,"offset":262},"end":{"line":14,"column":51,"offset":280}},"path":"test.js","line":14,"endline":14,"start":34,"end":51}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":34,"offset":262},"end":{"line":14,"column":51,"offset":280}},"path":"test.js","line":14,"endline":14,"start":34,"end":51},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"?any object\"\n },\n \"kind\":\"MaybeT\",\n \"type\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n}","type":"?Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":14,"column":50,"offset":278},"end":{"line":14,"column":50,"offset":279}},"path":"test.js","line":14,"endline":14,"start":50,"end":50},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"function\"\n },\n \"kind\":\"FunT\",\n \"static\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"statics of function\"\n },\n \"kind\":\"AnyFunT\"\n },\n \"prototype\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"empty prototype object\"\n },\n \"kind\":\"MixedT\"\n },\n \"funType\":{\n \"thisType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"global object\"\n },\n \"kind\":\"MixedT\"\n },\n \"paramTypes\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"?any object\"\n },\n \"kind\":\"MaybeT\",\n \"type\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n }\n ],\n \"paramNames\":[\"x\"],\n \"returnType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n },\n \"closureIndex\":0,\n \"changeset\":{\"vars\":[],\"refis\":[]}\n }\n}","type":"(x: ?Object) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":10,"offset":293},"end":{"line":15,"column":11,"offset":295}},"path":"test.js","line":15,"endline":15,"start":10,"end":11},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"?any object\"\n },\n \"kind\":\"MaybeT\",\n \"type\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n}","type":"?Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":13,"offset":296},"end":{"line":15,"column":22,"offset":306}},"path":"test.js","line":15,"endline":15,"start":13,"end":22},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"function\"\n },\n \"kind\":\"FunT\",\n \"static\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"statics of function\"\n },\n \"kind\":\"AnyFunT\"\n },\n \"prototype\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"empty prototype object\"\n },\n \"kind\":\"MixedT\"\n },\n \"funType\":{\n \"thisType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"global object\"\n },\n \"kind\":\"MixedT\"\n },\n \"paramTypes\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n }\n ],\n \"paramNames\":[\"val\"],\n \"returnType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n },\n \"closureIndex\":0,\n \"changeset\":{\"vars\":[],\"refis\":[]}\n }\n}","type":"(val: string | null | void | Object) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":34,"offset":317},"end":{"line":15,"column":48,"offset":332}},"path":"test.js","line":15,"endline":15,"start":34,"end":48},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n}","type":"string | void | Object","reasons":[{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":34,"offset":317},"end":{"line":15,"column":51,"offset":335}},"path":"test.js","line":15,"endline":15,"start":34,"end":51},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":34,"offset":317},"end":{"line":15,"column":51,"offset":335}},"path":"test.js","line":15,"endline":15,"start":34,"end":51},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":34,"offset":317},"end":{"line":15,"column":51,"offset":335}},"path":"test.js","line":15,"endline":15,"start":34,"end":51},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":34,"offset":317},"end":{"line":15,"column":51,"offset":335}},"path":"test.js","line":15,"endline":15,"start":34,"end":51}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":34,"offset":317},"end":{"line":15,"column":51,"offset":335}},"path":"test.js","line":15,"endline":15,"start":34,"end":51},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"?any object\"\n },\n \"kind\":\"MaybeT\",\n \"type\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n}","type":"?Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":15,"column":50,"offset":333},"end":{"line":15,"column":50,"offset":334}},"path":"test.js","line":15,"endline":15,"start":50,"end":50},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"function\"\n },\n \"kind\":\"FunT\",\n \"static\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"statics of function\"\n },\n \"kind\":\"AnyFunT\"\n },\n \"prototype\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"empty prototype object\"\n },\n \"kind\":\"MixedT\"\n },\n \"funType\":{\n \"thisType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"global object\"\n },\n \"kind\":\"MixedT\"\n },\n \"paramTypes\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"?string\"\n },\n \"kind\":\"MaybeT\",\n \"type\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n }\n }\n ],\n \"paramNames\":[\"x\"],\n \"returnType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n },\n \"closureIndex\":0,\n \"changeset\":{\"vars\":[],\"refis\":[]}\n }\n}","type":"(x: ?string) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":10,"offset":348},"end":{"line":16,"column":11,"offset":350}},"path":"test.js","line":16,"endline":16,"start":10,"end":11},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"?string\"\n },\n \"kind\":\"MaybeT\",\n \"type\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n }\n}","type":"?string","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":13,"offset":351},"end":{"line":16,"column":22,"offset":361}},"path":"test.js","line":16,"endline":16,"start":13,"end":22},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"function\"\n },\n \"kind\":\"FunT\",\n \"static\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"statics of function\"\n },\n \"kind\":\"AnyFunT\"\n },\n \"prototype\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"empty prototype object\"\n },\n \"kind\":\"MixedT\"\n },\n \"funType\":{\n \"thisType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"global object\"\n },\n \"kind\":\"MixedT\"\n },\n \"paramTypes\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n }\n ],\n \"paramNames\":[\"val\"],\n \"returnType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n },\n \"closureIndex\":0,\n \"changeset\":{\"vars\":[],\"refis\":[]}\n }\n}","type":"(val: string | null | void | Object) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":34,"offset":372},"end":{"line":16,"column":48,"offset":387}},"path":"test.js","line":16,"endline":16,"start":34,"end":48},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n}","type":"string | void | Object","reasons":[{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":34,"offset":372},"end":{"line":16,"column":51,"offset":390}},"path":"test.js","line":16,"endline":16,"start":34,"end":51},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":34,"offset":372},"end":{"line":16,"column":51,"offset":390}},"path":"test.js","line":16,"endline":16,"start":34,"end":51},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":34,"offset":372},"end":{"line":16,"column":51,"offset":390}},"path":"test.js","line":16,"endline":16,"start":34,"end":51},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":34,"offset":372},"end":{"line":16,"column":51,"offset":390}},"path":"test.js","line":16,"endline":16,"start":34,"end":51}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":34,"offset":372},"end":{"line":16,"column":51,"offset":390}},"path":"test.js","line":16,"endline":16,"start":34,"end":51},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"?string\"\n },\n \"kind\":\"MaybeT\",\n \"type\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n }\n}","type":"?string","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":16,"column":50,"offset":388},"end":{"line":16,"column":50,"offset":389}},"path":"test.js","line":16,"endline":16,"start":50,"end":50},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"function\"\n },\n \"kind\":\"FunT\",\n \"static\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"statics of function\"\n },\n \"kind\":\"AnyFunT\"\n },\n \"prototype\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"empty prototype object\"\n },\n \"kind\":\"MixedT\"\n },\n \"funType\":{\n \"thisType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"global object\"\n },\n \"kind\":\"MixedT\"\n },\n \"paramTypes\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"?string\"\n },\n \"kind\":\"MaybeT\",\n \"type\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n }\n }\n ],\n \"paramNames\":[\"x\"],\n \"returnType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n },\n \"closureIndex\":0,\n \"changeset\":{\"vars\":[],\"refis\":[]}\n }\n}","type":"(x: ?string) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":10,"offset":403},"end":{"line":17,"column":11,"offset":405}},"path":"test.js","line":17,"endline":17,"start":10,"end":11},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"?string\"\n },\n \"kind\":\"MaybeT\",\n \"type\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n }\n}","type":"?string","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":13,"offset":406},"end":{"line":17,"column":22,"offset":416}},"path":"test.js","line":17,"endline":17,"start":13,"end":22},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"function\"\n },\n \"kind\":\"FunT\",\n \"static\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"statics of function\"\n },\n \"kind\":\"AnyFunT\"\n },\n \"prototype\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"empty prototype object\"\n },\n \"kind\":\"MixedT\"\n },\n \"funType\":{\n \"thisType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"global object\"\n },\n \"kind\":\"MixedT\"\n },\n \"paramTypes\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"null\"\n },\n \"kind\":\"NullT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n }\n ],\n \"paramNames\":[\"val\"],\n \"returnType\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n },\n \"closureIndex\":0,\n \"changeset\":{\"vars\":[],\"refis\":[]}\n }\n}","type":"(val: string | null | void | Object) => string | void | Object","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":34,"offset":427},"end":{"line":17,"column":48,"offset":442}},"path":"test.js","line":17,"endline":17,"start":34,"end":48},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"union\"\n },\n \"kind\":\"UnionT\",\n \"types\":[\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"undefined\"\n },\n \"kind\":\"VoidT\"\n },\n {\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"any object\"\n },\n \"kind\":\"AnyObjT\"\n }\n ]\n}","type":"string | void | Object","reasons":[{"desc":"object type","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":34,"offset":427},"end":{"line":17,"column":51,"offset":445}},"path":"test.js","line":17,"endline":17,"start":34,"end":51},{"desc":"undefined","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":34,"offset":427},"end":{"line":17,"column":51,"offset":445}},"path":"test.js","line":17,"endline":17,"start":34,"end":51},{"desc":"null","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":34,"offset":427},"end":{"line":17,"column":51,"offset":445}},"path":"test.js","line":17,"endline":17,"start":34,"end":51},{"desc":"string","loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":34,"offset":427},"end":{"line":17,"column":51,"offset":445}},"path":"test.js","line":17,"endline":17,"start":34,"end":51}],"loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":34,"offset":427},"end":{"line":17,"column":51,"offset":445}},"path":"test.js","line":17,"endline":17,"start":34,"end":51},{"raw_type":"{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"?string\"\n },\n \"kind\":\"MaybeT\",\n \"type\":{\n \"reason\":{\n \"pos\":{\n \"source\":null,\n \"type\":null,\n \"start\":{\"line\":0,\"column\":1,\"offset\":0},\n \"end\":{\"line\":0,\"column\":0,\"offset\":0}\n },\n \"desc\":\"string\"\n },\n \"kind\":\"StrT\"\n }\n}","type":"?string","reasons":[],"loc":{"source":"test.js","type":"SourceFile","start":{"line":17,"column":50,"offset":443},"end":{"line":17,"column":50,"offset":444}},"path":"test.js","line":17,"endline":17,"start":50,"end":50}] diff --git a/tests/generators/class.js b/tests/generators/class.js index 3f7c711d238..c23ed1d59d8 100644 --- a/tests/generators/class.js +++ b/tests/generators/class.js @@ -100,13 +100,7 @@ var examples = new GeneratorExamples(); for (var x of examples.infer_stmt()) { (x : string) } // error: number ~> string -// We miss reporting an error number ~> boolean from the arg passed in the next -// call (below) to x in the infer_stmt function (above) via yield. This is a -// bug, arising due to a bad interaction between generics and union types (which -// appear in the signature of iterators, which in turn generators depend on). In -// particular, the error reappears when the iteration in the above line is -// commented. -var infer_stmt_next = examples.infer_stmt().next(0).value; +var infer_stmt_next = examples.infer_stmt().next(0).value; // error: number ~> boolean if (typeof infer_stmt_next === "undefined") { } else if (typeof infer_stmt_next === "number") { } else { diff --git a/tests/generators/class_failure.js b/tests/generators/class_failure.js index 48a3e660647..4a08be09768 100644 --- a/tests/generators/class_failure.js +++ b/tests/generators/class_failure.js @@ -11,10 +11,7 @@ var examples = new GeneratorExamples(); for (var x of examples.infer_stmt()) { (x : string) } // error: number ~> string -var infer_stmt_next = examples.infer_stmt().next(0).value; // this should be an - // error, but we miss - // it: see class.js - // for details +var infer_stmt_next = examples.infer_stmt().next(0).value; // error: number ~> boolean if (typeof infer_stmt_next === "undefined") { } else if (typeof infer_stmt_next === "number") { diff --git a/tests/generators/generators.exp b/tests/generators/generators.exp index 6d8a3069245..8c96859a27e 100644 --- a/tests/generators/generators.exp +++ b/tests/generators/generators.exp @@ -32,37 +32,45 @@ class.js:101 101: for (var x of examples.infer_stmt()) { (x : string) } // error: number ~> string ^^^^^^ string -class.js:109 -109: var infer_stmt_next = examples.infer_stmt().next(0).value; +class.js:103 +103: var infer_stmt_next = examples.infer_stmt().next(0).value; // error: number ~> boolean ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call of method `next` -113: (infer_stmt_next : boolean) // error: string ~> boolean +103: var infer_stmt_next = examples.infer_stmt().next(0).value; // error: number ~> boolean + ^ number. This type is incompatible with + 28: var x: ?boolean = yield 0; + ^^^^^^^ boolean + +class.js:103 +103: var infer_stmt_next = examples.infer_stmt().next(0).value; // error: number ~> boolean + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call of method `next` +107: (infer_stmt_next : boolean) // error: string ~> boolean ^^^^^^^^^^^^^^^ string. This type is incompatible with -113: (infer_stmt_next : boolean) // error: string ~> boolean +107: (infer_stmt_next : boolean) // error: string ~> boolean ^^^^^^^ boolean -class.js:128 -128: examples.delegate_next_generator().next(""); +class.js:122 +122: examples.delegate_next_generator().next(""); ^^ string. This type is incompatible with 50: var x: ?number = yield; // error: string ~> number ^^^^^^ number -class.js:131 -131: (x : number) // error: string ~> number +class.js:125 +125: (x : number) // error: string ~> number ^ string. This type is incompatible with -131: (x : number) // error: string ~> number +125: (x : number) // error: string ~> number ^^^^^^ number -class.js:134 -134: examples.delegate_next_iterable([]).next(""); // error: Iterator has no next value +class.js:128 +128: examples.delegate_next_iterable([]).next(""); // error: Iterator has no next value ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call of method `next` -134: examples.delegate_next_iterable([]).next(""); // error: Iterator has no next value +128: examples.delegate_next_iterable([]).next(""); // error: Iterator has no next value ^^ string. This type is incompatible with -undefined. See lib: core.js:405 +undefined. See lib: core.js:407 -class.js:137 -137: (x : string) // error: number ~> string +class.js:131 +131: (x : string) // error: number ~> string ^ number. This type is incompatible with -137: (x : string) // error: number ~> string +131: (x : string) // error: number ~> string ^^^^^^ string class_failure.js:12 @@ -72,11 +80,19 @@ class_failure.js:12 ^^^^^^ string class_failure.js:14 - 14: var infer_stmt_next = examples.infer_stmt().next(0).value; // this should be an + 14: var infer_stmt_next = examples.infer_stmt().next(0).value; // error: number ~> boolean + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call of method `next` + 14: var infer_stmt_next = examples.infer_stmt().next(0).value; // error: number ~> boolean + ^ number. This type is incompatible with + 5: var x: ?boolean = yield 0; + ^^^^^^^ boolean + +class_failure.js:14 + 14: var infer_stmt_next = examples.infer_stmt().next(0).value; // error: number ~> boolean ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call of method `next` - 22: (infer_stmt_next : boolean) // error: string ~> boolean + 19: (infer_stmt_next : boolean) // error: string ~> boolean ^^^^^^^^^^^^^^^ string. This type is incompatible with - 22: (infer_stmt_next : boolean) // error: string ~> boolean + 19: (infer_stmt_next : boolean) // error: string ~> boolean ^^^^^^^ boolean generators.js:3 @@ -142,7 +158,7 @@ generators.js:95 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call of method `next` 95: delegate_next_iterable([]).next(""); // error: Iterator has no next value ^^ string. This type is incompatible with -undefined. See lib: core.js:405 +undefined. See lib: core.js:407 generators.js:101 101: (x : string) // error: number ~> string @@ -183,4 +199,4 @@ throw.js:22 ^^^^^^ string -Found 28 errors +Found 30 errors diff --git a/tests/intersection/objassign.js b/tests/intersection/objassign.js index 2867ce4e7a2..fc0436123c6 100644 --- a/tests/intersection/objassign.js +++ b/tests/intersection/objassign.js @@ -3,7 +3,7 @@ * * Definitions in lib/lib.js * - * @flow + * @noflow */ declare var x: ObjAssignT; diff --git a/tests/intersection/test_fun.js b/tests/intersection/test_fun.js index c54484f1019..b9b2f81074b 100644 --- a/tests/intersection/test_fun.js +++ b/tests/intersection/test_fun.js @@ -11,7 +11,7 @@ * * Definitions lin lib/lib.js * - * @flow + * @noflow */ // intersection of function types satisfies union of param types diff --git a/tests/intersection/test_obj.js b/tests/intersection/test_obj.js index 4a436d9e608..6817584708a 100644 --- a/tests/intersection/test_obj.js +++ b/tests/intersection/test_obj.js @@ -1,7 +1,7 @@ /** * Tests for intersections of object types * - * @flow + * @noflow */ // TODO we should give explicit errors for incompatibilities diff --git a/tests/iterable/iterable.exp b/tests/iterable/iterable.exp index 1f8ce5a68db..1b3e3d039ae 100644 --- a/tests/iterable/iterable.exp +++ b/tests/iterable/iterable.exp @@ -24,45 +24,18 @@ caching_bug.js:21 iterator_result.js:23 23: return { done, value: "still going..." }; // Error string ~> void - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ object literal. This type is incompatible with - 20: next(): IteratorResult { - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ union: object type(s) - Member 1: - object type. See lib: core.js:393 - Error: - 23: return { done, value: "still going..." }; // Error string ~> void - ^^^^^^^^^^^^^^^^ string. This type is incompatible with - 20: next(): IteratorResult { - ^^^^ undefined - Member 2: - object type. See lib: core.js:396 - Error: - inconsistent use of library definitions - boolean literal `true`. Expected boolean literal `false`, got `true` instead. See lib: core.js:394 - boolean literal `false`. See lib: core.js:397 + ^^^^ boolean. Expected boolean literal `false`, got `true` instead +boolean literal `false`. See lib: core.js:399 iterator_result.js:25 25: return { done }; // Error void ~> string - ^^^^^^^^ object literal. This type is incompatible with - 20: next(): IteratorResult { - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ union: object type(s) - Member 1: - object type. See lib: core.js:393 - Error: - 25: return { done }; // Error void ~> string - ^^^^ boolean. Expected boolean literal `true`, got `false` instead - boolean literal `true`. See lib: core.js:394 - Member 2: - object type. See lib: core.js:396 - Error: - property `value`. Property not found in. See lib: core.js:396 - 25: return { done }; // Error void ~> string - ^^^^^^^^ object literal + ^^^^ boolean. Expected boolean literal `true`, got `false` instead +boolean literal `true`. See lib: core.js:396 map.js:13 13: function mapTest4(map: Map): Iterable { ^^^^^^ string. This type is incompatible with -tuple type. See lib: core.js:423 +tuple type. See lib: core.js:425 set.js:13 13: function setTest4(set: Set): Iterable { @@ -79,7 +52,7 @@ set.js:13 string.js:5 5: var stringTest3: Iterable = "hi"; // Error - string is a Iterable ^^^^^^ number. This type is incompatible with -string. See lib: core.js:234 +string. See lib: core.js:236 Found 10 errors diff --git a/tests/misc/misc.exp b/tests/misc/misc.exp index 4dfc8df40b1..14e08d286d1 100644 --- a/tests/misc/misc.exp +++ b/tests/misc/misc.exp @@ -79,7 +79,7 @@ G.js:6 ^^^^^^^^ assignment of property `length` 6: b.length = "duck"; ^^^^^^ string. This type is incompatible with -number. See lib: core.js:221 +number. See lib: core.js:223 G.js:7 7: b.length(); diff --git a/tests/node_tests/node_tests.exp b/tests/node_tests/node_tests.exp index 531f568d320..80f554f4c35 100644 --- a/tests/node_tests/node_tests.exp +++ b/tests/node_tests/node_tests.exp @@ -16,125 +16,41 @@ child_process/execSync.js:8 ^^^^^ string. This type is incompatible with number. See lib: node.js:113 +fs/fs.js:13 + 13: fs.readFile("file.exp", { encoding: "blah" }, (_, data) => { + ^ call of method `readFile`. Could not decide which case to select +intersection type. See lib: node.js:623 + Case 3 may work: + function type. See lib: node.js:632 + But if it doesn't, case 4 looks promising too: + function type. See lib: node.js:637 + Please provide additional annotation(s) to determine whether case 3 works (or consider merging it with case 4): + 13: fs.readFile("file.exp", { encoding: "blah" }, (_, data) => { + ^^^^ parameter `data` + fs/fs.js:24 24: (fs.readFileSync("file.exp") : string); // error - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ call of method `readFileSync`. Function cannot be called on any member of intersection type -intersection. See lib: node.js:642 - Member 1: - function type. See lib: node.js:642 - Error: - 24: (fs.readFileSync("file.exp") : string); // error - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Buffer. This type is incompatible with - 24: (fs.readFileSync("file.exp") : string); // error - ^^^^^^ string - Member 2: - function intersection. See lib: node.js:644 - Error: - 24: (fs.readFileSync("file.exp") : string); // error - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ undefined (too few arguments, expected default/rest parameters). This type is incompatible with - union: object type | string. See lib: node.js:644 - Member 1: - object type. See lib: node.js:644 - Error: - 24: (fs.readFileSync("file.exp") : string); // error - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ undefined (too few arguments, expected default/rest parameters). This type is incompatible with - object type. See lib: node.js:644 - Member 2: - string. See lib: node.js:643 - Error: - 24: (fs.readFileSync("file.exp") : string); // error - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ undefined (too few arguments, expected default/rest parameters). This type is incompatible with - string. See lib: node.js:643 - Member 3: - function type. See lib: node.js:645 - Error: - 24: (fs.readFileSync("file.exp") : string); // error - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ undefined (too few arguments, expected default/rest parameters). This type is incompatible with - object type. See lib: node.js:645 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Buffer. This type is incompatible with + 24: (fs.readFileSync("file.exp") : string); // error + ^^^^^^ string fs/fs.js:27 27: (fs.readFileSync("file.exp", "blah") : Buffer); // error - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call of method `readFileSync`. Function cannot be called on any member of intersection type -intersection. See lib: node.js:642 - Member 1: - function type. See lib: node.js:642 - Error: - 27: (fs.readFileSync("file.exp", "blah") : Buffer); // error - ^^^^^^ string. This type is incompatible with - undefined. See lib: node.js:642 - Member 2: - function intersection. See lib: node.js:644 - Error: - 27: (fs.readFileSync("file.exp", "blah") : Buffer); // error - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string. This type is incompatible with - 27: (fs.readFileSync("file.exp", "blah") : Buffer); // error - ^^^^^^ Buffer - Member 3: - function type. See lib: node.js:645 - Error: - 27: (fs.readFileSync("file.exp", "blah") : Buffer); // error - ^^^^^^ string. This type is incompatible with - object type. See lib: node.js:645 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string. This type is incompatible with + 27: (fs.readFileSync("file.exp", "blah") : Buffer); // error + ^^^^^^ Buffer fs/fs.js:30 30: (fs.readFileSync("file.exp", { encoding: "blah" }) : Buffer); // error - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call of method `readFileSync`. Function cannot be called on any member of intersection type -intersection. See lib: node.js:642 - Member 1: - function type. See lib: node.js:642 - Error: - 30: (fs.readFileSync("file.exp", { encoding: "blah" }) : Buffer); // error - ^^^^^^^^^^^^^^^^^^^^ object literal. This type is incompatible with - undefined. See lib: node.js:642 - Member 2: - function intersection. See lib: node.js:644 - Error: - 30: (fs.readFileSync("file.exp", { encoding: "blah" }) : Buffer); // error - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string. This type is incompatible with - 30: (fs.readFileSync("file.exp", { encoding: "blah" }) : Buffer); // error - ^^^^^^ Buffer - Member 3: - function type. See lib: node.js:645 - Error: - inconsistent use of library definitions - string. This type is incompatible with. See lib: node.js:644 - undefined. See lib: node.js:645 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string. This type is incompatible with + 30: (fs.readFileSync("file.exp", { encoding: "blah" }) : Buffer); // error + ^^^^^^ Buffer fs/fs.js:33 33: (fs.readFileSync("file.exp", {}) : string); // error - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call of method `readFileSync`. Function cannot be called on any member of intersection type -intersection. See lib: node.js:642 - Member 1: - function type. See lib: node.js:642 - Error: - 33: (fs.readFileSync("file.exp", {}) : string); // error - ^^ object literal. This type is incompatible with - undefined. See lib: node.js:642 - Member 2: - function intersection. See lib: node.js:644 - Error: - 33: (fs.readFileSync("file.exp", {}) : string); // error - ^^ object literal. This type is incompatible with - union: object type | string. See lib: node.js:644 - Member 1: - object type. See lib: node.js:644 - Error: - property `encoding`. Property not found in. See lib: node.js:644 - 33: (fs.readFileSync("file.exp", {}) : string); // error - ^^ object literal - Member 2: - string. See lib: node.js:643 - Error: - 33: (fs.readFileSync("file.exp", {}) : string); // error - ^^ object literal. This type is incompatible with - string. See lib: node.js:643 - Member 3: - function type. See lib: node.js:645 - Error: - 33: (fs.readFileSync("file.exp", {}) : string); // error - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Buffer. This type is incompatible with - 33: (fs.readFileSync("file.exp", {}) : string); // error - ^^^^^^ string + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Buffer. This type is incompatible with + 33: (fs.readFileSync("file.exp", {}) : string); // error + ^^^^^^ string invalid_package_file/package.json:1 1: @@ -223,4 +139,4 @@ json_file/test.js:22 ^^^^ undefined -Found 20 errors +Found 21 errors diff --git a/tests/object_api/object_api.exp b/tests/object_api/object_api.exp index 12678889cec..1ea28872bde 100644 --- a/tests/object_api/object_api.exp +++ b/tests/object_api/object_api.exp @@ -146,7 +146,7 @@ object_prototype.js:150 object_prototype.js:151 151: var xToLocaleString2 : () => number = x.toLocaleString; // error ^^^^^^ number. This type is incompatible with -string. See lib: core.js:341 +string. See lib: core.js:343 object_prototype.js:155 155: var yToLocaleString : number = y.toLocaleString; // error diff --git a/tests/objects/objects.exp b/tests/objects/objects.exp index a489542e61c..77d267cbc38 100644 --- a/tests/objects/objects.exp +++ b/tests/objects/objects.exp @@ -1,76 +1,14 @@ conversion.js:10 10: (Object(undefined): Number); // error - ^^^^^^^^^^^^^^^^^ function call. Function cannot be called on any member of intersection type + ^^^^^^^^^^^^^^^^^ object type. This type is incompatible with 10: (Object(undefined): Number); // error - ^^^^^^^^^^^^^^^^^ intersection - Member 1: - function type. See lib: core.js:28 - Error: - 10: (Object(undefined): Number); // error - ^^^^^^^^^^^^^^^^^ object type. This type is incompatible with - 10: (Object(undefined): Number); // error - ^^^^^^ Number - Member 2: - function type. See lib: core.js:29 - Error: - 10: (Object(undefined): Number); // error - ^^^^^^^^^ undefined. This type is incompatible with - boolean. See lib: core.js:29 - Member 3: - function type. See lib: core.js:30 - Error: - 10: (Object(undefined): Number); // error - ^^^^^^^^^ undefined. This type is incompatible with - number. See lib: core.js:30 - Member 4: - function type. See lib: core.js:31 - Error: - 10: (Object(undefined): Number); // error - ^^^^^^^^^ undefined. This type is incompatible with - string. See lib: core.js:31 - Member 5: - polymorphic type: function type. See lib: core.js:32 - Error: - 10: (Object(undefined): Number); // error - ^^^^^^^^^ undefined. This type is incompatible with - object type. See lib: core.js:32 + ^^^^^^ Number -conversion.js:18 - 18: var z = Object(123); // error (next line makes this not match any signatures) - ^^^^^^^^^^^ function call. Function cannot be called on any member of intersection type - 18: var z = Object(123); // error (next line makes this not match any signatures) - ^^^^^^^^^^^ intersection - Member 1: - function type. See lib: core.js:28 - Error: - 18: var z = Object(123); // error (next line makes this not match any signatures) - ^^^ number. This type is incompatible with - undefined. See lib: core.js:28 - Member 2: - function type. See lib: core.js:29 - Error: - 18: var z = Object(123); // error (next line makes this not match any signatures) - ^^^ number. This type is incompatible with - boolean. See lib: core.js:29 - Member 3: - function type. See lib: core.js:30 - Error: - 19: (z.charAt(0): string); - ^^^^^^ property `charAt`. Property not found in - 19: (z.charAt(0): string); - ^ Number - Member 4: - function type. See lib: core.js:31 - Error: - 18: var z = Object(123); // error (next line makes this not match any signatures) - ^^^ number. This type is incompatible with - string. See lib: core.js:31 - Member 5: - polymorphic type: function type. See lib: core.js:32 - Error: - 18: var z = Object(123); // error (next line makes this not match any signatures) - ^^^ number. This type is incompatible with - object type. See lib: core.js:32 +conversion.js:19 + 19: (z.charAt(0): string); + ^^^^^^ property `charAt`. Property not found in + 19: (z.charAt(0): string); + ^ Number objects.js:4 4: (x.foo : string); // error, key doesn't exist diff --git a/tests/overload/overload.exp b/tests/overload/overload.exp index 128980dd5d8..9ceb857e93a 100644 --- a/tests/overload/overload.exp +++ b/tests/overload/overload.exp @@ -27,19 +27,19 @@ overload.js:7 ^^^^^^^^^^^ call of method `match` 7: var x1: number = "".match(0)[0]; ^ number. This type is incompatible with -union: string | RegExp. See lib: core.js:246 +union: string | RegExp. See lib: core.js:248 Member 1: - string. See lib: core.js:246 + string. See lib: core.js:248 Error: 7: var x1: number = "".match(0)[0]; ^ number. This type is incompatible with - string. See lib: core.js:246 + string. See lib: core.js:248 Member 2: - RegExp. See lib: core.js:246 + RegExp. See lib: core.js:248 Error: 7: var x1: number = "".match(0)[0]; ^ number. This type is incompatible with - RegExp. See lib: core.js:246 + RegExp. See lib: core.js:248 overload.js:8 8: var x2: number = "".match(/pattern/)[0]; diff --git a/tests/promises/promises.exp b/tests/promises/promises.exp index c5da14e2edf..a32f55f1ec1 100644 --- a/tests/promises/promises.exp +++ b/tests/promises/promises.exp @@ -46,74 +46,31 @@ all.js:27 27: Promise.all(0); // Error: expected array instead of number ^ number -promise.js:10 - 10: new Promise(function(resolve, reject) { - ^ call of method `then` - 11: resolve(0); - ^ number. This type is incompatible with -union: type application of identifier `Promise` | type parameter `R` of constructor call. See lib: core.js:479 - Member 1: - type application of identifier `Promise`. See lib: core.js:479 - Error: - 11: resolve(0); - ^ number. This type is incompatible with - Promise. See lib: core.js:479 - Member 2: - 10: new Promise(function(resolve, reject) { - ^ type parameter `R` of constructor call - Error: - 16: var b: string = num; // Error: number ~> string +promise.js:16 + 16: var b: string = num; // Error: number ~> string + ^^^ number. This type is incompatible with + 16: var b: string = num; // Error: number ~> string + ^^^^^^ string + +promise.js:25 + 25: var b: string = num; // Error: number ~> string ^^^ number. This type is incompatible with - 16: var b: string = num; // Error: number ~> string + 25: var b: string = num; // Error: number ~> string ^^^^^^ string -promise.js:20 - 20: new Promise((resolve, reject) => resolve(0)) - ^ call of method `then` - 20: new Promise((resolve, reject) => resolve(0)) - ^ number. This type is incompatible with -union: type application of identifier `Promise` | type parameter `R` of constructor call. See lib: core.js:479 - Member 1: - type application of identifier `Promise`. See lib: core.js:479 - Error: - 20: new Promise((resolve, reject) => resolve(0)) - ^ number. This type is incompatible with - Promise. See lib: core.js:479 - Member 2: - 20: new Promise((resolve, reject) => resolve(0)) - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `R` of constructor call - Error: - 25: var b: string = num; // Error: number ~> string - ^^^ number. This type is incompatible with - 25: var b: string = num; // Error: number ~> string - ^^^^^^ string - promise.js:30 30: resolve(new Promise(function(resolve, reject) { ^ constructor call 30: resolve(new Promise(function(resolve, reject) { ^ Promise. This type is incompatible with -union: type application of identifier `Promise` | type parameter `R` of constructor call. See lib: core.js:479 +union: type application of identifier `Promise` | type parameter `R` of constructor call. See lib: core.js:476 Member 1: - type application of identifier `Promise`. See lib: core.js:479 + type application of identifier `Promise`. See lib: core.js:476 Error: - 31: resolve(0); - ^ number. This type is incompatible with - union: type application of identifier `Promise` | type parameter `R` of constructor call. See lib: core.js:479 - Member 1: - type application of identifier `Promise`. See lib: core.js:479 - Error: - 31: resolve(0); - ^ number. This type is incompatible with - Promise. See lib: core.js:479 - Member 2: - 30: resolve(new Promise(function(resolve, reject) { - ^ type parameter `R` of constructor call - Error: - 35: var b: string = num; // Error: number ~> string - ^^^ number. This type is incompatible with - 35: var b: string = num; // Error: number ~> string - ^^^^^^ string + 35: var b: string = num; // Error: number ~> string + ^^^ number. This type is incompatible with + 35: var b: string = num; // Error: number ~> string + ^^^^^^ string Member 2: 29: new Promise(function(resolve, reject) { ^ type parameter `R` of constructor call @@ -128,27 +85,14 @@ promise.js:41 ^ constructor call 41: resolve(new Promise(function(resolve, reject) { ^ Promise. This type is incompatible with -union: type application of identifier `Promise` | type parameter `R` of constructor call. See lib: core.js:479 +union: type application of identifier `Promise` | type parameter `R` of constructor call. See lib: core.js:476 Member 1: - type application of identifier `Promise`. See lib: core.js:479 + type application of identifier `Promise`. See lib: core.js:476 Error: - 42: resolve(0); - ^ number. This type is incompatible with - union: type application of identifier `Promise` | type parameter `R` of constructor call. See lib: core.js:479 - Member 1: - type application of identifier `Promise`. See lib: core.js:479 - Error: - 42: resolve(0); - ^ number. This type is incompatible with - Promise. See lib: core.js:479 - Member 2: - 41: resolve(new Promise(function(resolve, reject) { - ^ type parameter `R` of constructor call - Error: - 47: var b: string = num; // Error: number ~> string - ^^^ number. This type is incompatible with - 47: var b: string = num; // Error: number ~> string - ^^^^^^ string + 47: var b: string = num; // Error: number ~> string + ^^^ number. This type is incompatible with + 47: var b: string = num; // Error: number ~> string + ^^^^^^ string Member 2: 40: resolve(new Promise(function(resolve, reject) { ^ type parameter `R` of constructor call @@ -158,74 +102,31 @@ union: type application of identifier `Promise` | type parameter `R` of construc 46: var a: number = num; ^^^^^^ number -promise.js:51 - 51: new Promise(function(resolve, reject) { - ^ call of method `then` - 53: resolve(42); - ^^ number. This type is incompatible with -union: type application of identifier `Promise` | type parameter `R` of constructor call. See lib: core.js:479 - Member 1: - type application of identifier `Promise`. See lib: core.js:479 - Error: - 53: resolve(42); - ^^ number. This type is incompatible with - Promise. See lib: core.js:479 - Member 2: - 51: new Promise(function(resolve, reject) { - ^ type parameter `R` of constructor call - Error: - 63: var c: string = numOrStr; // Error: number|string -> string - ^^^^^^^^ number. This type is incompatible with - 63: var c: string = numOrStr; // Error: number|string -> string - ^^^^^^ string +promise.js:63 + 63: var c: string = numOrStr; // Error: number|string -> string + ^^^^^^^^ number. This type is incompatible with + 63: var c: string = numOrStr; // Error: number|string -> string + ^^^^^^ string -promise.js:115 -115: Promise.resolve(0).then(function(num) { - ^ call of method `then` -115: Promise.resolve(0).then(function(num) { - ^ number. This type is incompatible with -union: type application of identifier `Promise` | type parameter `T` of call of method `resolve`. See lib: core.js:492 - Member 1: - type application of identifier `Promise`. See lib: core.js:492 - Error: - 115: Promise.resolve(0).then(function(num) { - ^ number. This type is incompatible with - Promise. See lib: core.js:492 - Member 2: - 115: Promise.resolve(0).then(function(num) { - ^^^^^^^^^^^^^^^^^^ type parameter `T` of call of method `resolve` - Error: - 117: var b: string = num; // Error: number ~> string - ^^^ number. This type is incompatible with - 117: var b: string = num; // Error: number ~> string - ^^^^^^ string +promise.js:117 +117: var b: string = num; // Error: number ~> string + ^^^ number. This type is incompatible with +117: var b: string = num; // Error: number ~> string + ^^^^^^ string promise.js:121 121: Promise.resolve(Promise.resolve(0)).then(function(num) { ^^^^^^^^^^^^^^^^^^ call of method `resolve` 121: Promise.resolve(Promise.resolve(0)).then(function(num) { ^^^^^^^^^^^^^^^^^^ Promise. This type is incompatible with -union: type application of identifier `Promise` | type parameter `T` of call of method `resolve`. See lib: core.js:492 +union: type application of identifier `Promise` | type parameter `T` of call of method `resolve`. See lib: core.js:489 Member 1: - type application of identifier `Promise`. See lib: core.js:492 + type application of identifier `Promise`. See lib: core.js:489 Error: - 121: Promise.resolve(Promise.resolve(0)).then(function(num) { - ^ number. This type is incompatible with - union: type application of identifier `Promise` | type parameter `T` of call of method `resolve`. See lib: core.js:492 - Member 1: - type application of identifier `Promise`. See lib: core.js:492 - Error: - 121: Promise.resolve(Promise.resolve(0)).then(function(num) { - ^ number. This type is incompatible with - Promise. See lib: core.js:492 - Member 2: - 121: Promise.resolve(Promise.resolve(0)).then(function(num) { - ^^^^^^^^^^^^^^^^^^ type parameter `T` of call of method `resolve` - Error: - 123: var b: string = num; // Error: number ~> string - ^^^ number. This type is incompatible with - 123: var b: string = num; // Error: number ~> string - ^^^^^^ string + 123: var b: string = num; // Error: number ~> string + ^^^ number. This type is incompatible with + 123: var b: string = num; // Error: number ~> string + ^^^^^^ string Member 2: 121: Promise.resolve(Promise.resolve(0)).then(function(num) { ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` of call of method `resolve` @@ -240,27 +141,14 @@ promise.js:127 ^^^^^^^^^^^^^^^^^^ call of method `resolve` 127: Promise.resolve(Promise.resolve(Promise.resolve(0))).then(function(num) { ^^^^^^^^^^^^^^^^^^ Promise. This type is incompatible with -union: type application of identifier `Promise` | type parameter `T` of call of method `resolve`. See lib: core.js:492 +union: type application of identifier `Promise` | type parameter `T` of call of method `resolve`. See lib: core.js:489 Member 1: - type application of identifier `Promise`. See lib: core.js:492 + type application of identifier `Promise`. See lib: core.js:489 Error: - 127: Promise.resolve(Promise.resolve(Promise.resolve(0))).then(function(num) { - ^ number. This type is incompatible with - union: type application of identifier `Promise` | type parameter `T` of call of method `resolve`. See lib: core.js:492 - Member 1: - type application of identifier `Promise`. See lib: core.js:492 - Error: - 127: Promise.resolve(Promise.resolve(Promise.resolve(0))).then(function(num) { - ^ number. This type is incompatible with - Promise. See lib: core.js:492 - Member 2: - 127: Promise.resolve(Promise.resolve(Promise.resolve(0))).then(function(num) { - ^^^^^^^^^^^^^^^^^^ type parameter `T` of call of method `resolve` - Error: - 129: var b: string = num; // Error: number ~> string - ^^^ number. This type is incompatible with - 129: var b: string = num; // Error: number ~> string - ^^^^^^ string + 129: var b: string = num; // Error: number ~> string + ^^^ number. This type is incompatible with + 129: var b: string = num; // Error: number ~> string + ^^^^^^ string Member 2: 127: Promise.resolve(Promise.resolve(Promise.resolve(0))).then(function(num) { ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` of call of method `resolve` @@ -270,53 +158,25 @@ union: type application of identifier `Promise` | type parameter `T` of call of 128: var a: number = num; ^^^^^^ number -promise.js:157 -157: Promise.resolve(0) - ^ call of method `then` -158: .then(function(num) { return 'asdf'; }) - ^^^^^^ string. This type is incompatible with -union: type application of identifier `Promise` | type parameter `U` of call of method `then`. See lib: core.js:484 - Member 1: - type application of identifier `Promise`. See lib: core.js:484 - Error: - 158: .then(function(num) { return 'asdf'; }) - ^^^^^^ string. This type is incompatible with - Promise. See lib: core.js:484 - Member 2: - 157: Promise.resolve(0) - ^ type parameter `U` of call of method `then` - Error: - 161: var b: number = str; // Error: string ~> number - ^^^ string. This type is incompatible with - 161: var b: number = str; // Error: string ~> number - ^^^^^^ number +promise.js:161 +161: var b: number = str; // Error: string ~> number + ^^^ string. This type is incompatible with +161: var b: number = str; // Error: string ~> number + ^^^^^^ number promise.js:166 166: .then(function(num) { return Promise.resolve('asdf'); }) ^^^^^^^^^^^^^^^^^^^^^^^ call of method `resolve` 166: .then(function(num) { return Promise.resolve('asdf'); }) ^^^^^^^^^^^^^^^^^^^^^^^ Promise. This type is incompatible with -union: type application of identifier `Promise` | type parameter `U` of call of method `then`. See lib: core.js:484 +union: type application of identifier `Promise` | type parameter `U` of call of method `then`. See lib: core.js:481 Member 1: - type application of identifier `Promise`. See lib: core.js:484 + type application of identifier `Promise`. See lib: core.js:481 Error: - 166: .then(function(num) { return Promise.resolve('asdf'); }) - ^^^^^^ string. This type is incompatible with - union: type application of identifier `Promise` | type parameter `T` of call of method `resolve`. See lib: core.js:492 - Member 1: - type application of identifier `Promise`. See lib: core.js:492 - Error: - 166: .then(function(num) { return Promise.resolve('asdf'); }) - ^^^^^^ string. This type is incompatible with - Promise. See lib: core.js:492 - Member 2: - 166: .then(function(num) { return Promise.resolve('asdf'); }) - ^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` of call of method `resolve` - Error: - 169: var b: number = str; // Error: string ~> number - ^^^ string. This type is incompatible with - 169: var b: number = str; // Error: string ~> number - ^^^^^^ number + 169: var b: number = str; // Error: string ~> number + ^^^ string. This type is incompatible with + 169: var b: number = str; // Error: string ~> number + ^^^^^^ number Member 2: 165: Promise.resolve(0) ^ type parameter `U` of call of method `then` @@ -331,27 +191,14 @@ promise.js:174 ^^^^^^^^^^^^^^^^^^^^^^^ call of method `resolve` 174: .then(function(num) { return Promise.resolve(Promise.resolve('asdf')); }) ^^^^^^^^^^^^^^^^^^^^^^^ Promise. This type is incompatible with -union: type application of identifier `Promise` | type parameter `T` of call of method `resolve`. See lib: core.js:492 +union: type application of identifier `Promise` | type parameter `T` of call of method `resolve`. See lib: core.js:489 Member 1: - type application of identifier `Promise`. See lib: core.js:492 + type application of identifier `Promise`. See lib: core.js:489 Error: - 174: .then(function(num) { return Promise.resolve(Promise.resolve('asdf')); }) - ^^^^^^ string. This type is incompatible with - union: type application of identifier `Promise` | type parameter `T` of call of method `resolve`. See lib: core.js:492 - Member 1: - type application of identifier `Promise`. See lib: core.js:492 - Error: - 174: .then(function(num) { return Promise.resolve(Promise.resolve('asdf')); }) - ^^^^^^ string. This type is incompatible with - Promise. See lib: core.js:492 - Member 2: - 174: .then(function(num) { return Promise.resolve(Promise.resolve('asdf')); }) - ^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` of call of method `resolve` - Error: - 177: var b: number = str; // Error: string ~> number - ^^^ string. This type is incompatible with - 177: var b: number = str; // Error: string ~> number - ^^^^^^ number + 177: var b: number = str; // Error: string ~> number + ^^^ string. This type is incompatible with + 177: var b: number = str; // Error: string ~> number + ^^^^^^ number Member 2: 174: .then(function(num) { return Promise.resolve(Promise.resolve('asdf')); }) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` of call of method `resolve` @@ -361,53 +208,25 @@ union: type application of identifier `Promise` | type parameter `T` of call of 176: var a: string = str; ^^^^^^ string -promise.js:197 -197: Promise.reject(0) - ^ call of method `then` -198: .catch(function(num) { return 'asdf'; }) - ^^^^^^ string. This type is incompatible with -union: ?type application of identifier `Promise` | type parameter `U` of call of method `catch`. See lib: core.js:489 - Member 1: - ?type application of identifier `Promise`. See lib: core.js:489 - Error: - 198: .catch(function(num) { return 'asdf'; }) - ^^^^^^ string. This type is incompatible with - Promise. See lib: core.js:489 - Member 2: - 197: Promise.reject(0) - ^ type parameter `U` of call of method `catch` - Error: - 201: var b: number = str; // Error: string ~> number - ^^^ string. This type is incompatible with - 201: var b: number = str; // Error: string ~> number - ^^^^^^ number +promise.js:201 +201: var b: number = str; // Error: string ~> number + ^^^ string. This type is incompatible with +201: var b: number = str; // Error: string ~> number + ^^^^^^ number promise.js:206 206: .catch(function(num) { return Promise.resolve('asdf'); }) ^^^^^^^^^^^^^^^^^^^^^^^ call of method `resolve` 206: .catch(function(num) { return Promise.resolve('asdf'); }) ^^^^^^^^^^^^^^^^^^^^^^^ Promise. This type is incompatible with -union: ?type application of identifier `Promise` | type parameter `U` of call of method `catch`. See lib: core.js:489 +union: ?type application of identifier `Promise` | type parameter `U` of call of method `catch`. See lib: core.js:486 Member 1: - ?type application of identifier `Promise`. See lib: core.js:489 + ?type application of identifier `Promise`. See lib: core.js:486 Error: - 206: .catch(function(num) { return Promise.resolve('asdf'); }) - ^^^^^^ string. This type is incompatible with - union: type application of identifier `Promise` | type parameter `T` of call of method `resolve`. See lib: core.js:492 - Member 1: - type application of identifier `Promise`. See lib: core.js:492 - Error: - 206: .catch(function(num) { return Promise.resolve('asdf'); }) - ^^^^^^ string. This type is incompatible with - Promise. See lib: core.js:492 - Member 2: - 206: .catch(function(num) { return Promise.resolve('asdf'); }) - ^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` of call of method `resolve` - Error: - 209: var b: number = str; // Error: string ~> number - ^^^ string. This type is incompatible with - 209: var b: number = str; // Error: string ~> number - ^^^^^^ number + 209: var b: number = str; // Error: string ~> number + ^^^ string. This type is incompatible with + 209: var b: number = str; // Error: string ~> number + ^^^^^^ number Member 2: 205: Promise.reject(0) ^ type parameter `U` of call of method `catch` @@ -422,27 +241,14 @@ promise.js:214 ^^^^^^^^^^^^^^^^^^^^^^^ call of method `resolve` 214: .catch(function(num) { return Promise.resolve(Promise.resolve('asdf')); }) ^^^^^^^^^^^^^^^^^^^^^^^ Promise. This type is incompatible with -union: type application of identifier `Promise` | type parameter `T` of call of method `resolve`. See lib: core.js:492 +union: type application of identifier `Promise` | type parameter `T` of call of method `resolve`. See lib: core.js:489 Member 1: - type application of identifier `Promise`. See lib: core.js:492 + type application of identifier `Promise`. See lib: core.js:489 Error: - 214: .catch(function(num) { return Promise.resolve(Promise.resolve('asdf')); }) - ^^^^^^ string. This type is incompatible with - union: type application of identifier `Promise` | type parameter `T` of call of method `resolve`. See lib: core.js:492 - Member 1: - type application of identifier `Promise`. See lib: core.js:492 - Error: - 214: .catch(function(num) { return Promise.resolve(Promise.resolve('asdf')); }) - ^^^^^^ string. This type is incompatible with - Promise. See lib: core.js:492 - Member 2: - 214: .catch(function(num) { return Promise.resolve(Promise.resolve('asdf')); }) - ^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` of call of method `resolve` - Error: - 217: var b: number = str; // Error: string ~> number - ^^^ string. This type is incompatible with - 217: var b: number = str; // Error: string ~> number - ^^^^^^ number + 217: var b: number = str; // Error: string ~> number + ^^^ string. This type is incompatible with + 217: var b: number = str; // Error: string ~> number + ^^^^^^ number Member 2: 214: .catch(function(num) { return Promise.resolve(Promise.resolve('asdf')); }) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` of call of method `resolve` diff --git a/tests/refinements/tagged_union.js b/tests/refinements/tagged_union.js index 8cad3c0b0bf..2da4af6cf24 100644 --- a/tests/refinements/tagged_union.js +++ b/tests/refinements/tagged_union.js @@ -38,7 +38,7 @@ function bar(x: Breakfast) { function qux(x: Breakfast) { if (x.taste === 'Good') { (x.raw: 'Yes' | 'No'); // 2 errors: - // Apple.raw doesn't exist + // Orange.raw doesn't exist // Carrot.raw is neither Yes nor No } } diff --git a/tests/union/union.exp b/tests/union/union.exp index 99c3c348b43..19f834fd6dd 100644 --- a/tests/union/union.exp +++ b/tests/union/union.exp @@ -1,23 +1,8 @@ -issue-198.js:1 - 1: var p = new Promise(function(resolve, reject) { - ^ call of method `then` - 5: return num.toFixed(); - ^^^^^^^^^^^^^ string. This type is incompatible with -union: type application of identifier `Promise` | type parameter `U` of call of method `then`. See lib: core.js:484 - Member 1: - type application of identifier `Promise`. See lib: core.js:484 - Error: - 5: return num.toFixed(); - ^^^^^^^^^^^^^ string. This type is incompatible with - Promise. See lib: core.js:484 - Member 2: - 1: var p = new Promise(function(resolve, reject) { - ^ type parameter `U` of call of method `then` - Error: - 9: return str.toFixed(); - ^^^^^^^ property `toFixed`. Property not found in - 9: return str.toFixed(); - ^^^ String +issue-198.js:9 + 9: return str.toFixed(); + ^^^^^^^ property `toFixed`. Property not found in + 9: return str.toFixed(); + ^^^ String issue-324.js:8 8: foostr = barstr; diff --git a/tests/union_new/.flowconfig b/tests/union_new/.flowconfig new file mode 100644 index 00000000000..9ab45296181 --- /dev/null +++ b/tests/union_new/.flowconfig @@ -0,0 +1,2 @@ +[libs] +lib \ No newline at end of file diff --git a/tests/union_new/issue-1349.js b/tests/union_new/issue-1349.js new file mode 100644 index 00000000000..3bb5c9f3ba3 --- /dev/null +++ b/tests/union_new/issue-1349.js @@ -0,0 +1,6 @@ +/* @flow */ + +var bar: Array<{b: ?boolean, c: number} | {b: boolean}> = [ + {b: true, c: 123}, + {b: true} +]; diff --git a/tests/union_new/issue-1371.js b/tests/union_new/issue-1371.js new file mode 100644 index 00000000000..e46b4059ea6 --- /dev/null +++ b/tests/union_new/issue-1371.js @@ -0,0 +1,7 @@ +function create(a: any): { type: 'B', data: number } | { type: 'A', data: string } +{ + return { + type: 'A', + data: a + } +} diff --git a/tests/union_new/issue-1455-helper.js b/tests/union_new/issue-1455-helper.js new file mode 100644 index 00000000000..a483642f842 --- /dev/null +++ b/tests/union_new/issue-1455-helper.js @@ -0,0 +1,3 @@ +/* @flow */ + +export class Foobar { } diff --git a/tests/union_new/issue-1455.js b/tests/union_new/issue-1455.js new file mode 100644 index 00000000000..1163aaf9331 --- /dev/null +++ b/tests/union_new/issue-1455.js @@ -0,0 +1,9 @@ +/* @flow */ +import type {Foobar} from "./issue-1455-helper" + +function create(content: ?Foobar | String | Array) { +} + +function node(content: ?Foobar | String | Array) { + create(content) +} diff --git a/tests/union_new/issue-1462-i.js b/tests/union_new/issue-1462-i.js new file mode 100644 index 00000000000..e844d3b7822 --- /dev/null +++ b/tests/union_new/issue-1462-i.js @@ -0,0 +1,22 @@ +type Common = { +}; + +type A = Common & { + type: 'A', + foo: number +}; + +type B = Common & { + type: 'B', + foo: Array +} + +type MyType = A | B; + +function print(x: number) { + console.log(x); +} + +function printAll(val: MyType) { + print(val.foo); // <--- foo could be an array +} diff --git a/tests/union_new/issue-1462-ii.js b/tests/union_new/issue-1462-ii.js new file mode 100644 index 00000000000..260eb7c1901 --- /dev/null +++ b/tests/union_new/issue-1462-ii.js @@ -0,0 +1,27 @@ +type Common = { +}; + +type A = { + type: 'A', + foo: number +} & Common; + +type B = { + type: 'B', + foo: Array +} & Common; + +type MyType = A | B; + + +function print(x: number) { + console.log(x); +} + +function printAll(val: MyType) { + if (val.type === 'A') { + print(val.foo); + } else { + val.foo.forEach(print); + } +} diff --git a/tests/union_new/issue-1664.js b/tests/union_new/issue-1664.js new file mode 100644 index 00000000000..e2d1e2d5042 --- /dev/null +++ b/tests/union_new/issue-1664.js @@ -0,0 +1,26 @@ +/* @flow */ + +type DataBase = { + id: string, + name: string, +}; + +type UserData = DataBase & { + kind: "user", +}; + +type SystemData = DataBase & { + kind: "system", +} + +type Data = UserData | SystemData; + +const data: Data = { + id: "", + name: "", + kind: "system", +} + +if (data.kind === "system") { + (data: SystemData); +} diff --git a/tests/union_new/issue-1759.js b/tests/union_new/issue-1759.js new file mode 100644 index 00000000000..af3a1a3fe51 --- /dev/null +++ b/tests/union_new/issue-1759.js @@ -0,0 +1,8 @@ +// @flow + +type X = ({a:true} & {b:string}) | ({a:false} & {c:string}); +//type X = {a:true, b:string} | {a:false, c:string}; // this works. + +function hello(x:X): string { + if (x.a === true) return x.b; else return x.c; +} diff --git a/tests/union_new/issue-815.js b/tests/union_new/issue-815.js new file mode 100644 index 00000000000..44f2bed4b09 --- /dev/null +++ b/tests/union_new/issue-815.js @@ -0,0 +1,21 @@ +/* @flow */ +type T = A|B; +class U {}; +declare var children: U; +(children: T|U); +class A {}; +class B {}; + +type VirtualElement = Thunk|VirtualNode; +type Child = VirtualElement; +type Children = Array; + + +class Thunk {} +class VirtualNode { + children: Child|Children; + constructor(type, children/*:Children*/) { + this.children = children.length === 1 ? children[0] : + children; + } +} diff --git a/tests/union_new/issue-824-helper.js b/tests/union_new/issue-824-helper.js new file mode 100644 index 00000000000..289eb998e50 --- /dev/null +++ b/tests/union_new/issue-824-helper.js @@ -0,0 +1,12 @@ +import A from "./issue-824"; + +export class B extends A { + which(): number { + return 1; + } +} +export class C extends A { + which(): number { + return 2; + } +} diff --git a/tests/union_new/issue-824.js b/tests/union_new/issue-824.js new file mode 100644 index 00000000000..655e03d1391 --- /dev/null +++ b/tests/union_new/issue-824.js @@ -0,0 +1,16 @@ +import { B, C } from "./issue-824-helper"; + +type K = B | C; + +type I = { + which(): number; +}; + +export default class A { + static foo(p: K): bool { + return false; + } + static bar(p: I & K): bool { + return this.foo(p); + } +} diff --git a/tests/union_new/lib/test23_lib.js b/tests/union_new/lib/test23_lib.js new file mode 100644 index 00000000000..a0b41766ae6 --- /dev/null +++ b/tests/union_new/lib/test23_lib.js @@ -0,0 +1 @@ +declare class SomeLibClass { } diff --git a/tests/union_new/lib/test25_lib.js b/tests/union_new/lib/test25_lib.js new file mode 100644 index 00000000000..d79c71a20c1 --- /dev/null +++ b/tests/union_new/lib/test25_lib.js @@ -0,0 +1,21 @@ +declare class Set { + add(): Set; +} + +declare class Row { + reduce_row( + callbackfn: (previousValue: number, currentValue: number) => number, + initialValue: void + ): number; + reduce_row( + callbackfn: (previousValue: U, currentValue: number) => U, + initialValue: U + ): U; +} + +declare class Rows { + reduce_rows( + callbackfn: (previousValue: X, currentValue: Row) => X, + initialValue: X + ): X; +} diff --git a/tests/union_new/lib/test32_lib.js b/tests/union_new/lib/test32_lib.js new file mode 100644 index 00000000000..e0daf1518b2 --- /dev/null +++ b/tests/union_new/lib/test32_lib.js @@ -0,0 +1 @@ +type Indirect = Array; diff --git a/tests/union_new/test1.js b/tests/union_new/test1.js new file mode 100644 index 00000000000..10758e4134b --- /dev/null +++ b/tests/union_new/test1.js @@ -0,0 +1,60 @@ +// @noflow + +/** + * Test that shows how the implementation of union types is broken + */ + +////////////////////////////// +// example with object types +////////////////////////////// + +function obj(a: A1 | A2) { + return a.x; +} + +const obj_result = obj({ x: "" }); // currently an error! (expect it to be OK) + +// Type definitions used above are defined below, but in an order that +// deliberately makes their full resolution as lazy as possible. The call above +// blocks until A1 is partially resolved. Since the argument partially matches +// A1, that branch is selected. Later, that branch errors, but other branches +// have been lost by then. + +type A1 = { x: B1 }; +type A2 = { x: B2 }; + +type B1 = number; +type B2 = string; + +(obj_result: B1 | B2); + +/////////////////////////////////////// +// similar example with function types +/////////////////////////////////////// + +function fun(a: A3 | A4) { + return a(); +} + +const fun_result = fun(() => ""); + +type A3 = () => B3; +type A4 = () => B4; + +type B3 = number; +type B4 = string; + +(fun_result: B3 | B4); + +///////////////////////////////////////////// +// similar example with class instance types +///////////////////////////////////////////// + +function inst(a: A5 | A6) { } + +class B5 { } +class B6 { } +inst([new B6]); + +type A5 = B5[]; +type A6 = B6[]; diff --git a/tests/union_new/test10.js b/tests/union_new/test10.js new file mode 100644 index 00000000000..deaa835fe34 --- /dev/null +++ b/tests/union_new/test10.js @@ -0,0 +1,72 @@ +// @noflow + +function id(x: X): X { return x; } + +///////////////////////// +// primitive annotations +///////////////////////// + +function check_prim(_: number | string) { } + +// ok +check_prim(""); + +// ...even when they "flow" in +check_prim(id("")); + +////////////////////////////// +// class instance annotations +////////////////////////////// + +class C { } +class D { } +function check_inst(_: C | D) { } + +// ok +check_inst(new D); + +// ...even when they "flow" in +check_inst(id(new C)); + +//////////////////////// +// function annotations +//////////////////////// + +function check_fun(_: ((_: number) => number) | ((_: string) => string)) { } + +// help! +check_fun((x) => x); + +////////////////////// +// object annotations +////////////////////// + +function check_obj(_: { x: number } | { x: string }) { } + +// ok +check_obj({ x: "" }); + +// help! +check_obj({ x: id("") }); + +///////////////////// +// array annotations +///////////////////// + +function check_arr(_: number[] | string[]) { } + +// ok +check_arr([""]); + +// help! +check_arr([id("")]); + +////////////////////////////////////// +// generic class instance annotations +////////////////////////////////////// + +class P { } +function check_poly_inst(_: P | P) { } + +// help! +check_poly_inst(new P); diff --git a/tests/union_new/test11.js b/tests/union_new/test11.js new file mode 100644 index 00000000000..c5a02b7fbf8 --- /dev/null +++ b/tests/union_new/test11.js @@ -0,0 +1,18 @@ +// @noflow + +// disjoint unions + +function length(list: List) { + if (list.kind === "cons") return length(list.next) + 1; + else return 0; +} + + +length({ kind: "nil" }); +length({ kind: "cons" }); // missing `next` +length({ kind: "cons", next: { kind: "nil" } }); +length({ kind: "empty" }); // `kind` not found + +type List = Nil | Cons; +type Nil = { kind: "nil" }; +type Cons = { kind: "cons", next: List }; diff --git a/tests/union_new/test12.js b/tests/union_new/test12.js new file mode 100644 index 00000000000..45aff3456d3 --- /dev/null +++ b/tests/union_new/test12.js @@ -0,0 +1,9 @@ +// @noflow + +// polymorphic recursive types + +type F = { f: F, x: X } +type G = { x: number } +type H = { x: string } + +function rec(x: F): G | H { return x; } diff --git a/tests/union_new/test13.js b/tests/union_new/test13.js new file mode 100644 index 00000000000..89333fc536a --- /dev/null +++ b/tests/union_new/test13.js @@ -0,0 +1,11 @@ +// @noflow + +/* ensure there are no unintended side effects when trying branches */ + +({type: 'B', id: 'hi'}: { + type: 'A'; + id: ?string; +} | { + type: 'B'; + id: string; +}); diff --git a/tests/union_new/test14.js b/tests/union_new/test14.js new file mode 100644 index 00000000000..8b69352cd59 --- /dev/null +++ b/tests/union_new/test14.js @@ -0,0 +1,13 @@ +// @noflow + +// annotations + +declare class C { + get(): X; +} + +function union(o: { x: string } | { x: number }) { } + +function foo(c: C) { + union({ x: c.get() }); +} diff --git a/tests/union_new/test15.js b/tests/union_new/test15.js new file mode 100644 index 00000000000..f5044b04f12 --- /dev/null +++ b/tests/union_new/test15.js @@ -0,0 +1,18 @@ +// @noflow + +// functions as objects + +function foo(target: EventTarget) { + target.addEventListener('click', (e) => {}); +} + +declare class EventTarget { + addEventListener(type: 'foo', listener: KeyboardEventHandler): void; + addEventListener(type: string, listener: EventHandler): void; +} + +declare class Event { } +declare class KeyboardEvent { } + +type EventHandler = (event: Event) => mixed +type KeyboardEventHandler = (event: KeyboardEvent) => mixed diff --git a/tests/union_new/test16.js b/tests/union_new/test16.js new file mode 100644 index 00000000000..0debe2bd0a8 --- /dev/null +++ b/tests/union_new/test16.js @@ -0,0 +1,18 @@ +// @noflow + +// annotations + +type T = number | (() => string); +type Foo = T | (() => bool); + +type Bar = number | (() => string) | (() => bool); + +function foo(x: Foo) { } +foo(() => qux()); + +function bar(x: Bar) { } +bar(() => qux()); + +var x = false; +function qux() { return x; } +x = ""; diff --git a/tests/union_new/test17.js b/tests/union_new/test17.js new file mode 100644 index 00000000000..919fa91246c --- /dev/null +++ b/tests/union_new/test17.js @@ -0,0 +1,7 @@ +// @noflow + +// Array#concat + +[].concat([]); + +([].concat([0,1])[1]: string) diff --git a/tests/union_new/test18.js b/tests/union_new/test18.js new file mode 100644 index 00000000000..6ae2bbd21c8 --- /dev/null +++ b/tests/union_new/test18.js @@ -0,0 +1,12 @@ +// @noflow + +// method overloads + +declare class C { + m(x: number): void; + m(x: string): void; +} + +function f() { return 0; } + +new C().m(f()); diff --git a/tests/union_new/test19.js b/tests/union_new/test19.js new file mode 100644 index 00000000000..2178cdf8a7d --- /dev/null +++ b/tests/union_new/test19.js @@ -0,0 +1,12 @@ +// @noflow + +// constructor overloads + +function m() { + return new D(); +} + +declare class D { + constructor(_: void): void; + constructor(_: null): void; +} diff --git a/tests/union_new/test2.js b/tests/union_new/test2.js new file mode 100644 index 00000000000..4647de3ccdf --- /dev/null +++ b/tests/union_new/test2.js @@ -0,0 +1,77 @@ +// @noflow + +/** + * Test that shows how the implementation of union types is broken + */ + +////////////////////////////// +// example with object types +////////////////////////////// + +function obj(a: { x: number } | { x: string }) { } + +obj(({ x: "" }: A1)); + +type A1 = { x: B1 }; + +type B1 = string; + +/////////////////////////////////////// +// similar example with function types +/////////////////////////////////////// + +function fun(a: (() => number) | (() => string)) { } + +fun(((() => ""): A2)); + +type A2 = () => B2; + +type B2 = string; + +///////////////////////////////////////////////////// +// similar example with generic class instance types +///////////////////////////////////////////////////// + +class C { } + +function inst(a: C | C) { } + +inst((new C: A3)); + +type A3 = C; + +type B3 = string; + +///////////////////////////////////////////// +// similar example with generic type aliases +///////////////////////////////////////////// + +function alias(a: T | T) { } +alias({ x: (x: V) => { } }); + +type T = { x: U } +type U = (x: V) => void; +type V = X; + +type B4 = string; + +// class statics + +function stat(a: { x: number } | { x: string }) { } + +class D { + static x: B5; +} + +stat(D); + +type B5 = string; + +// tuples + +function tup(a: [number,boolean] | [string,boolean]) { } + +tup((["",false]: A6)); + +type A6 = [B6,boolean]; +type B6 = string; diff --git a/tests/union_new/test20.js b/tests/union_new/test20.js new file mode 100644 index 00000000000..1aaab84f794 --- /dev/null +++ b/tests/union_new/test20.js @@ -0,0 +1,14 @@ +// @noflow + +// Array#reduce + +[0,1].reduce((x,y,i) => y); + +["a", "b"].reduce( + (regex, representation, index) => { + return regex + (index ? '|' : '') + '(' + representation + ')'; + }, + '', +); + +[""].reduce((acc,str) => acc * str.length); diff --git a/tests/union_new/test21.js b/tests/union_new/test21.js new file mode 100644 index 00000000000..9f68c948537 --- /dev/null +++ b/tests/union_new/test21.js @@ -0,0 +1,21 @@ +// @noflow + +// annotations for disjoint unions + +type T = + | { type: "FOO", x: number } + | { type: "BAR", x: string } + +({ type: (bar(): "BAR"), x: str() }: T); + +({ type: bar(), x: str() }: T); + +({ type: bar(), x: (str(): string) }: T); + +function bar() { + return "BAR"; +} + +function str() { + return "hello"; +} diff --git a/tests/union_new/test22.js b/tests/union_new/test22.js new file mode 100644 index 00000000000..2b7a263f859 --- /dev/null +++ b/tests/union_new/test22.js @@ -0,0 +1,21 @@ +// @noflow + +// refinement of disjoint unions + +type Empty = { } + +type Success = { + type: 'SUCCESS'; + result: string; +}; + +type Error = { + type: 'ERROR'; +} & Empty; + +export type T = Success | Error; + +function foo(x: T) { + if (x.type === 'SUCCESS') return x.result; + else return x.result; +} diff --git a/tests/union_new/test23.js b/tests/union_new/test23.js new file mode 100644 index 00000000000..ad65416fcff --- /dev/null +++ b/tests/union_new/test23.js @@ -0,0 +1,12 @@ +// @noflow + +// nested intersections (see also lib/test23_lib.js) + +type NestedObj = { } & { dummy: SomeLibClass }; + +type Obj = NestedObj & { x: string }; + +function foo(obj: Obj) { + obj.x; // should be OK + obj.x; // should also be OK (the check above shouldn't affect anything) +} diff --git a/tests/union_new/test24.js b/tests/union_new/test24.js new file mode 100644 index 00000000000..98d2d704242 --- /dev/null +++ b/tests/union_new/test24.js @@ -0,0 +1,30 @@ +// @noflow + +// scaling test for full type resolution + +declare class C { + addListener(event: string, listener: Function): C; + emit(event: string, ...args:Array): boolean; + listeners(event: string): Array; + listenerCount(event: string): number; + on(event: string, listener: Function): C; + once(event: string, listener: Function): C; + removeAllListeners(event?: string): C; + removeListener(event: string, listener: Function): C; + setMaxListeners(n: number): void; +} + +declare class D extends C { + listen(port: number, hostname?: string, backlog?: number, callback?: Function): D; + listen(path: string, callback?: Function): D; + listen(handle: Object, callback?: Function): D; + close(callback?: Function): D; + address(): number; + connections: number; + maxConnections: number; + getConnections(callback: Function): void; + ref(): D; + unref(): D; +} + +(0: D | number); diff --git a/tests/union_new/test25.js b/tests/union_new/test25.js new file mode 100644 index 00000000000..581bed11d03 --- /dev/null +++ b/tests/union_new/test25.js @@ -0,0 +1,13 @@ +// @noflow + +// termination test (see also lib/test25_lib.js) + +function foo(rows: Rows, set: Set) { + return rows.reduce_rows( + (set, row) => row.reduce_row( + (set, i) => set.add(i), + set, + ), + set, + ); +} diff --git a/tests/union_new/test26.js b/tests/union_new/test26.js new file mode 100644 index 00000000000..501c49c1eaa --- /dev/null +++ b/tests/union_new/test26.js @@ -0,0 +1,20 @@ +// @noflow + +declare function foo(x: number): number; +declare function foo(x: string): string; + +declare var x: number | string; + +(foo(x): number | string); + +type T = number | string; +declare var y: T; + +(foo(y): T); + +declare class Record { + set(x: 'foo', y: number): void; + set(x: 'bar', y: string): void; +} + +new Record().set('foo', "42"); diff --git a/tests/union_new/test27.js b/tests/union_new/test27.js new file mode 100644 index 00000000000..823609224da --- /dev/null +++ b/tests/union_new/test27.js @@ -0,0 +1,20 @@ +// @noflow + +type X = ({a:true} & {b:string}) | ({a:false} & {c:string}); +//type X = {a:true, b:string} | {a:false, c:string}; // this works. + +function hello1(x:X): string { + if (x.a === true) return x.b; else return x.c; +} + +function hello2(x:X): string { + if (x.a === false) return x.c; else return x.b; +} + +function hello3(x:X): string { + if (x.a) { return x.b; } else { return x.c; } +} + +function hello4(x:X): string { + if (!x.a) { return x.c; } else { return x.b; } +} diff --git a/tests/union_new/test28-helper.js b/tests/union_new/test28-helper.js new file mode 100644 index 00000000000..f4fbe000ee1 --- /dev/null +++ b/tests/union_new/test28-helper.js @@ -0,0 +1,69 @@ +// @noflow + +const TABLE_WIDTH = 500; + +const BASE_COLUMNS = [ + { + key: '0', + width: Math.round(TABLE_WIDTH / 6), + isFixed: true, + extra: { + dataKey: 0, + label: 'ID', + }, + }, + { + key: '1', + width: Math.round(TABLE_WIDTH / 3), + isFixed: true, + extra: { + dataKey: 1, + label: 'A', + }, + }, + { + key: '2', + width: Math.round(TABLE_WIDTH / 4), + extra: { + dataKey: 2, + label: 'B', + }, + }, + { + key: '3', + width: Math.round(TABLE_WIDTH / 2), + extra: { + dataKey: 3, + label: 'C', + }, + }, + { + key: '4', + width: 200, + extra: { + dataKey: 4, + label: 'D', + }, + }, + { + key: '5', + width: 200, + extra: { + dataKey: 5, + label: 'E', + }, + }, + { + key: '6', + width: 200, + extra: { + dataKey: 6, + label: 'F', + }, + }, +]; + +module.exports = { + TABLE_WIDTH, + BASE_COLUMNS, +}; diff --git a/tests/union_new/test28.js b/tests/union_new/test28.js new file mode 100644 index 00000000000..0daffce1112 --- /dev/null +++ b/tests/union_new/test28.js @@ -0,0 +1,19 @@ +// @noflow + +const { + TABLE_WIDTH, + BASE_COLUMNS, +} = require('./test28-helper'); + +const columns = [...BASE_COLUMNS]; +for (let i = 0; i < 1000; ++i) { + const dataKey = (i % 4) + 1; + columns.push({ + key: `${dataKey}`, + width: Math.round(TABLE_WIDTH / 16), + extra: { + dataKey, + label: `${i}`, + }, + }); +} diff --git a/tests/union_new/test29.js b/tests/union_new/test29.js new file mode 100644 index 00000000000..5db89360ada --- /dev/null +++ b/tests/union_new/test29.js @@ -0,0 +1,31 @@ +// @noflow + +// Make sure caching doesn't cause a spurious successful match (e.g., when a +// failed match is tried again). This may happen, e.g., when checking +// polymorphic definitions, where the same code may be checked multiple times +// with different instantiations. + +type Row = { x: string }; + +declare class D { + reduce( + callbackfn: (previousValue: T, currentValue: T) => T, + initialValue: void + ): T; + reduce( + callbackfn: (previousValue: U, currentValue: T) => U, + initialValue: U + ): U; +} + +class C { + foo( + rows: D, + minWidth: number, + ): number { + return rows.reduce( + (length, row) => 0, + minWidth, + ); + } +} diff --git a/tests/union_new/test3.js b/tests/union_new/test3.js new file mode 100644 index 00000000000..fd12e5fd150 --- /dev/null +++ b/tests/union_new/test3.js @@ -0,0 +1,29 @@ +// @noflow + +/** + * Test that shows how the implementation of union types is broken + */ + +/////////////////////////////// +// example with function types +/////////////////////////////// + +function fun(a: ((x: number) => void) | ((x: string) => void)) { } + +fun((((x) => {}): A1)); + +type A1 = (x: B1) => void; + +type B1 = string; + +//////////////////////////// +// example with array types +//////////////////////////// + +function arr(a: number[] | string[]) { } + +arr(([]: A2)); + +type A2 = B2[]; + +type B2 = string; diff --git a/tests/union_new/test30-helper.js b/tests/union_new/test30-helper.js new file mode 100644 index 00000000000..b4eccdb1422 --- /dev/null +++ b/tests/union_new/test30-helper.js @@ -0,0 +1,6 @@ +// @noflow + +module.exports = { + FOO: 'foo', + BAR: 'bar', +} diff --git a/tests/union_new/test30.js b/tests/union_new/test30.js new file mode 100644 index 00000000000..96ec6ec5618 --- /dev/null +++ b/tests/union_new/test30.js @@ -0,0 +1,9 @@ +// @noflow + +const Constants = require('./test30-helper'); + +type ActionType = + | { type: 'foo', x: number } + | { type: 'bar', x: number } + +({ type: Constants.BAR, x: 0 }: ActionType); diff --git a/tests/union_new/test31.js b/tests/union_new/test31.js new file mode 100644 index 00000000000..23c2642bb22 --- /dev/null +++ b/tests/union_new/test31.js @@ -0,0 +1,25 @@ +// @noflow + +// make sure tuples are type arguments (as used e.g. when viewing maps as +// key/value iterables) work + +interface SomeIterator { } + +interface SomeIterable { + it(): SomeIterator; +} + +declare class SomeMap { + it(): SomeIterator<[K,V]>; + set(k: K, v: V): void; +} + +declare class ImmutableMap { } + +declare function convert(iter: SomeIterable<[K,V]>): ImmutableMap; + +function foo(): ImmutableMap { + const countersGlobalMap = new SomeMap(); + countersGlobalMap.set("", false); + return convert(countersGlobalMap); +} diff --git a/tests/union_new/test32.js b/tests/union_new/test32.js new file mode 100644 index 00000000000..b6f730ec9a3 --- /dev/null +++ b/tests/union_new/test32.js @@ -0,0 +1,9 @@ +// @flow + +// make sure that full resolution jobs don't cache improperly to signal success +// when they have failed earlier + +function foo(value: Indirect | number): Indirect | number { + const castedValue: number = typeof value === 'number' ? value : 0; + return castedValue; +} diff --git a/tests/union_new/test4.js b/tests/union_new/test4.js new file mode 100644 index 00000000000..93dd1dccaac --- /dev/null +++ b/tests/union_new/test4.js @@ -0,0 +1,36 @@ +// @noflow + +/** + * Test that shows how the implementation of union types is broken + */ + +/////////////////////////////// +// example with function types +/////////////////////////////// + +function fun(a: ((x: number) => void) | ((x: string) => void)) { } + +const a1 = ((x) => {}: A1); +fun(a1); + +function fun_call(x: string) { a1(x); } + +type A1 = (x: B1) => void; + +type B1 = string; + +//////////////////////////// +// example with array types +//////////////////////////// + +function arr(a: number[] | string[]) { } + +const a2 = ([]: A2); +arr(a2); + +function arr_set(x: string, i: number) { a2[i] = x; } +function arr_get(i: number): string { return a2[i]; } + +type A2 = B2[]; + +type B2 = string; diff --git a/tests/union_new/test5.js b/tests/union_new/test5.js new file mode 100644 index 00000000000..0222e8f934f --- /dev/null +++ b/tests/union_new/test5.js @@ -0,0 +1,27 @@ +// @noflow + +/** + * Test that shows how the implementation of union types is broken + */ + +/////////////////////////////// +// example with function types +/////////////////////////////// + +function fun(a: ((x: number) => number) | ((x: string) => string)) { } + +function a1(x) { return x; } +fun(a1); + +function fun_call(x: string): string { return a1(x); } + +///////////////////////////// +// example with array types +///////////////////////////// + +function arr(a: number[] | string[]) { } + +var a2 = []; +arr(a2); + +function arr_set(x: string, i: number) { a2[i] = x; } diff --git a/tests/union_new/test6.js b/tests/union_new/test6.js new file mode 100644 index 00000000000..c780bb84835 --- /dev/null +++ b/tests/union_new/test6.js @@ -0,0 +1,25 @@ +// @noflow + +/** + * Test that shows how the implementation of union types is broken + */ + +////////////////////////////////////////// +// example with generic class inheritance +////////////////////////////////////////// + +function inst(a: E): C | C { return a; } + +const mk_C = () => C; +const mk_D = () => D; +const mk_E = () => E; + +type B4 = string; + +const _D = mk_D(); +class E extends _D { } + +const _C = mk_C(); +class D extends _C { } + +class C { } diff --git a/tests/union_new/test7.js b/tests/union_new/test7.js new file mode 100644 index 00000000000..1f9f5713b93 --- /dev/null +++ b/tests/union_new/test7.js @@ -0,0 +1,29 @@ +// @noflow + +/** + * Test that shows how the implementation of union types is broken + */ + +//////////////////// +// recursive types +//////////////////// + +function rec(x: F1 | F2) { } +rec({ x: 0 }); + +type F1 = G1; +type F2 = G2; +type G1 = { x: H1, y?: G1 }; +type G2 = { x: H2, y?: G2 }; +type H1 = string; +type H2 = number; + +/////////////////////////////// +// polymorphic recursive types +/////////////////////////////// + +function polyrec(x: PF | PF) { } +rec({ x: 0 }); + +type PF = PG; +type PG = { x: X, y?: PG }; diff --git a/tests/union_new/test8.js b/tests/union_new/test8.js new file mode 100644 index 00000000000..4afbc4c62b5 --- /dev/null +++ b/tests/union_new/test8.js @@ -0,0 +1,23 @@ +// @noflow + +/** + * Test that shows how the implementation of union types is broken + */ + +////////////////////// +// nested union types +////////////////////// + +function rec(x: F1 | F2) { } +rec({ x: 0 }); + +type F1 = G1 | G1_; +type F2 = G2 | G2_; +type G1 = { x: H1 }; +type G1_ = { x: H1_ }; +type G2 = { x: H2 }; +type G2_ = { x: H2_ }; +type H1 = boolean; +type H1_ = string; +type H2 = boolean; +type H2_ = number; diff --git a/tests/union_new/test9.js b/tests/union_new/test9.js new file mode 100644 index 00000000000..18221e5d82c --- /dev/null +++ b/tests/union_new/test9.js @@ -0,0 +1,16 @@ +// @noflow + +/** + * Test that shows how the implementation of union types is broken + */ + +//////////////// +// interference +//////////////// + +function square(x? = 0) { + return x * x; +} + +function foo(f: ((_: ?number) => ?number) | (() => void)) { } +foo((x): number => square(x)) diff --git a/tests/union_new/union_new.exp b/tests/union_new/union_new.exp new file mode 100644 index 00000000000..87df02cacfc --- /dev/null +++ b/tests/union_new/union_new.exp @@ -0,0 +1,332 @@ +issue-1462-i.js:21 + 21: print(val.foo); // <--- foo could be an array + ^^^^^^^^^^^^^^ function call + 21: print(val.foo); // <--- foo could be an array + ^^^^^^^ array type. This type is incompatible with + 16: function print(x: number) { + ^^^^^^ number + +test1.js:39 + 39: const fun_result = fun(() => ""); + ^^^^^^^^ arrow function. Could not decide which case to select + 35: function fun(a: A3 | A4) { + ^^^^^^^ union type + Case 1 may work: + 35: function fun(a: A3 | A4) { + ^^ A3 + But if it doesn't, case 2 looks promising too: + 35: function fun(a: A3 | A4) { + ^^ A4 + Please provide additional annotation(s) to determine whether case 1 works (or consider merging it with case 2): + 39: const fun_result = fun(() => ""); + ^^ return + +test1.js:57 + 57: inst([new B6]); + ^^^^^^^^ array literal. Could not decide which case to select + 53: function inst(a: A5 | A6) { } + ^^^^^^^ union type + Case 1 may work: + 53: function inst(a: A5 | A6) { } + ^^ A5 + But if it doesn't, case 2 looks promising too: + 53: function inst(a: A5 | A6) { } + ^^ A6 + Please provide additional annotation(s) to determine whether case 1 works (or consider merging it with case 2): + 57: inst([new B6]); + ^^^^^^ constructor call + +test10.js:38 + 38: check_fun((x) => x); + ^^^^^^^^ arrow function. Could not decide which case to select + 35: function check_fun(_: ((_: number) => number) | ((_: string) => string)) { } + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ union type + Case 1 may work: + 35: function check_fun(_: ((_: number) => number) | ((_: string) => string)) { } + ^^^^^^^^^^^^^^^^^^^^^ function type + But if it doesn't, case 2 looks promising too: + 35: function check_fun(_: ((_: number) => number) | ((_: string) => string)) { } + ^^^^^^^^^^^^^^^^^^^^^ function type + Please provide additional annotation(s) to determine whether case 1 works (or consider merging it with case 2): + 38: check_fun((x) => x); + ^ parameter `x` + 38: check_fun((x) => x); + ^ return + +test10.js:50 + 50: check_obj({ x: id("") }); + ^^^^^^^^^^^^^ object literal. Could not decide which case to select + 44: function check_obj(_: { x: number } | { x: string }) { } + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ union type + Case 1 may work: + 44: function check_obj(_: { x: number } | { x: string }) { } + ^^^^^^^^^^^^^ object type + But if it doesn't, case 2 looks promising too: + 44: function check_obj(_: { x: number } | { x: string }) { } + ^^^^^^^^^^^^^ object type + Please provide additional annotation(s) to determine whether case 1 works (or consider merging it with case 2): + 50: check_obj({ x: id("") }); + ^^^^^^ function call + +test10.js:62 + 62: check_arr([id("")]); + ^^^^^^^^ array literal. Could not decide which case to select + 56: function check_arr(_: number[] | string[]) { } + ^^^^^^^^^^^^^^^^^^^ union type + Case 1 may work: + 56: function check_arr(_: number[] | string[]) { } + ^^^^^^^^ array type + But if it doesn't, case 2 looks promising too: + 56: function check_arr(_: number[] | string[]) { } + ^^^^^^^^ array type + Please provide additional annotation(s) to determine whether case 1 works (or consider merging it with case 2): + 62: check_arr([id("")]); + ^^^^^^ function call + +test11.js:12 + 12: length({ kind: "cons" }); // missing `next` + ^^^^^^^^^^^^^^^^ object literal. This type is incompatible with + 5: function length(list: List) { + ^^^^ union: Nil | Cons + Member 1: + 16: type List = Nil | Cons; + ^^^ Nil + Error: + 12: length({ kind: "cons" }); // missing `next` + ^^^^^^ string. Expected string literal `nil`, got `cons` instead + 17: type Nil = { kind: "nil" }; + ^^^^^ string literal `nil` + Member 2: + 16: type List = Nil | Cons; + ^^^^ Cons + Error: + 16: type List = Nil | Cons; + ^^^^ property `next`. Property not found in + 12: length({ kind: "cons" }); // missing `next` + ^^^^^^^^^^^^^^^^ object literal + +test11.js:14 + 14: length({ kind: "empty" }); // `kind` not found + ^^^^^^^^^^^^^^^^^ object literal. This type is incompatible with + 5: function length(list: List) { + ^^^^ union: Nil | Cons + Member 1: + 16: type List = Nil | Cons; + ^^^ Nil + Error: + 14: length({ kind: "empty" }); // `kind` not found + ^^^^^^^ string. Expected string literal `nil`, got `empty` instead + 17: type Nil = { kind: "nil" }; + ^^^^^ string literal `nil` + Member 2: + 16: type List = Nil | Cons; + ^^^^ Cons + Error: + 14: length({ kind: "empty" }); // `kind` not found + ^^^^^^^ string. Expected string literal `cons`, got `empty` instead + 18: type Cons = { kind: "cons", next: List }; + ^^^^^^ string literal `cons` + +test14.js:12 + 12: union({ x: c.get() }); + ^^^^^^^^^^^^^^ object literal. Could not decide which case to select + 9: function union(o: { x: string } | { x: number }) { } + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ union type + Case 1 may work: + 9: function union(o: { x: string } | { x: number }) { } + ^^^^^^^^^^^^^ object type + But if it doesn't, case 2 looks promising too: + 9: function union(o: { x: string } | { x: number }) { } + ^^^^^^^^^^^^^ object type + Please provide additional annotation(s) to determine whether case 1 works (or consider merging it with case 2): + 12: union({ x: c.get() }); + ^^^^^^^ call of method `get` + +test16.js:11 + 11: foo(() => qux()); + ^^^^^^^^^^^ arrow function. Could not decide which case to select + 10: function foo(x: Foo) { } + ^^^ union type + Case 1 may work: + 6: type Foo = T | (() => bool); + ^ T + But if it doesn't, case 2 looks promising too: + 6: type Foo = T | (() => bool); + ^^^^^^^^^^ function type + Please provide additional annotation(s) to determine whether case 1 works (or consider merging it with case 2): + 11: foo(() => qux()); + ^^^^^ return + +test16.js:14 + 14: bar(() => qux()); + ^^^^^^^^^^^ arrow function. Could not decide which case to select + 13: function bar(x: Bar) { } + ^^^ union type + Case 2 may work: + 8: type Bar = number | (() => string) | (() => bool); + ^^^^^^^^^^^^ function type + But if it doesn't, case 3 looks promising too: + 8: type Bar = number | (() => string) | (() => bool); + ^^^^^^^^^^ function type + Please provide additional annotation(s) to determine whether case 2 works (or consider merging it with case 3): + 14: bar(() => qux()); + ^^^^^ return + +test17.js:7 + 7: ([].concat([0,1])[1]: string) + ^^^^^^^^^^^^^^^^ call of method `concat` + 7: ([].concat([0,1])[1]: string) + ^ number. This type is incompatible with + 7: ([].concat([0,1])[1]: string) + ^^^^^^ string + +test17.js:7 + 7: ([].concat([0,1])[1]: string) + ^^^^^^^^^^^^^^^^ call of method `concat` + 7: ([].concat([0,1])[1]: string) + ^ number. This type is incompatible with + 7: ([].concat([0,1])[1]: string) + ^^^^^^ string + +test20.js:14 + 14: [""].reduce((acc,str) => acc * str.length); + ^^^ string. This type is incompatible with + 14: [""].reduce((acc,str) => acc * str.length); + ^^^^^^^^^^^^^^^^ number + +test20.js:14 + 14: [""].reduce((acc,str) => acc * str.length); + ^^^^^^^^^^^^^^^^ number. This type is incompatible with + 14: [""].reduce((acc,str) => acc * str.length); + ^^ string + +test21.js:11 + 11: ({ type: bar(), x: str() }: T); + ^^^^^^^^^^^^^^^^^^^^^^^^^ object literal. Could not decide which case to select + 11: ({ type: bar(), x: str() }: T); + ^ union type + Case 1 may work: + 6: | { type: "FOO", x: number } + ^^^^^^^^^^^^^^^^^^^^^^^^^^ object type + But if it doesn't, case 2 looks promising too: + 7: | { type: "BAR", x: string } + ^^^^^^^^^^^^^^^^^^^^^^^^^^ object type + Please provide additional annotation(s) to determine whether case 1 works (or consider merging it with case 2): + 11: ({ type: bar(), x: str() }: T); + ^^^^^ function call + 11: ({ type: bar(), x: str() }: T); + ^^^^^ function call + +test22.js:20 + 20: else return x.result; + ^^^^^^^^ property `result`. Property cannot be accessed on any member of intersection type + 20: else return x.result; + ^ intersection + Member 1: + 12: type Error = { + ^ object type + Error: + 20: else return x.result; + ^^^^^^ property `result`. Property not found in + 12: type Error = { + ^ object type + Member 2: + 14: } & Empty; + ^^^^^ Empty + Error: + 20: else return x.result; + ^^^^^^ property `result`. Property not found in + 14: } & Empty; + ^^^^^ object type + +test26.js:20 + 20: new Record().set('foo', "42"); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call of method `set`. Function cannot be called on any member of intersection type + 20: new Record().set('foo', "42"); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ intersection + Member 1: + 16: set(x: 'foo', y: number): void; + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function type + Error: + 20: new Record().set('foo', "42"); + ^^^^ string. This type is incompatible with + 16: set(x: 'foo', y: number): void; + ^^^^^^ number + Member 2: + 17: set(x: 'bar', y: string): void; + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function type + Error: + 20: new Record().set('foo', "42"); + ^^^^^ string. Expected string literal `bar`, got `foo` instead + 17: set(x: 'bar', y: string): void; + ^^^^^ string literal `bar` + +test28.js:11 + 11: columns.push({ + ^ object literal. Could not decide which case to select + 5: const BASE_COLUMNS = [ + ^ inferred union of array element types (alternatively, provide an annotation to summarize the array element type). See: test28-helper.js:5 + Case 1 may work: + 56: { + ^ object literal. See: test28-helper.js:56 + But if it doesn't, case 2 looks promising too: + 48: { + ^ object literal. See: test28-helper.js:48 + Please provide additional annotation(s) to determine whether case 1 works (or consider merging it with case 2): + 15: dataKey, + ^^^^^^^ identifier `dataKey` + 12: key: `${dataKey}`, + ^^^^^^^^^^^^ string + 16: label: `${i}`, + ^^^^^^ string + +test5.js:14 + 14: fun(a1); + ^^ function. Could not decide which case to select + 11: function fun(a: ((x: number) => number) | ((x: string) => string)) { } + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ union type + Case 1 may work: + 11: function fun(a: ((x: number) => number) | ((x: string) => string)) { } + ^^^^^^^^^^^^^^^^^^^^^ function type + But if it doesn't, case 2 looks promising too: + 11: function fun(a: ((x: number) => number) | ((x: string) => string)) { } + ^^^^^^^^^^^^^^^^^^^^^ function type + Please provide additional annotation(s) to determine whether case 1 works (or consider merging it with case 2): + 13: function a1(x) { return x; } + ^ parameter `x` + 13: function a1(x) { return x; } + ^ return + +test5.js:25 + 25: arr(a2); + ^^ empty array literal. Could not decide which case to select + 22: function arr(a: number[] | string[]) { } + ^^^^^^^^^^^^^^^^^^^ union type + Case 1 may work: + 22: function arr(a: number[] | string[]) { } + ^^^^^^^^ array type + But if it doesn't, case 2 looks promising too: + 22: function arr(a: number[] | string[]) { } + ^^^^^^^^ array type + Please provide additional annotation(s) to determine whether case 1 works (or consider merging it with case 2): + 24: var a2 = []; + ^^ unknown element type of empty array + +test9.js:16 + 16: foo((x): number => square(x)) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function call + 12: return x * x; + ^ null. This type is incompatible with + 12: return x * x; + ^^^^^ number + +test9.js:16 + 16: foo((x): number => square(x)) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function call + 12: return x * x; + ^ null. This type is incompatible with + 12: return x * x; + ^^^^^ number + + +Found 23 errors