From 10d4393443eba108d674d1ecbde5a8144d75478c Mon Sep 17 00:00:00 2001 From: George Zahariev Date: Tue, 10 Dec 2024 10:53:41 -0800 Subject: [PATCH] [flow] Update how `typeof x === 'object'` on `typeof x === 'function'` is empty Summary: Changelog: [errors] If you have refiend a value based on `typeof x === 'function'`, and then do `typeof x === 'object'`, the result is now `empty` as that is impossible. Reviewed By: SamChou19815 Differential Revision: D67031335 fbshipit-source-id: e0c11ddec6cc2dfc71000c600dab882fab6e3489 --- src/typing/type_filter.ml | 2 +- tests/refinements/mixed.js | 9 +++++++++ tests/refinements/refinements.exp | 33 ++++++++++++++++++++++++++++++- 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/typing/type_filter.ml b/src/typing/type_filter.ml index 75b6dbf1b7e..9d1f5be35b9 100644 --- a/src/typing/type_filter.ml +++ b/src/typing/type_filter.ml @@ -522,7 +522,7 @@ let rec object_ cx t = | Mixed_non_maybe | Mixed_non_null -> obj |> changed_result - | Mixed_function + | Mixed_function -> DefT (reason_of_t t, EmptyT) |> changed_result | Mixed_everything | Mixed_non_void -> let reason = replace_desc_new_reason RUnion (reason_of_t t) in diff --git a/tests/refinements/mixed.js b/tests/refinements/mixed.js index 2014624bb06..e4fa67d677f 100644 --- a/tests/refinements/mixed.js +++ b/tests/refinements/mixed.js @@ -128,3 +128,12 @@ const loop = (condition: boolean) => { } } }; + +{ + declare const x: mixed; + if (typeof x === 'function') { + if (typeof x === 'object') { + x as empty; // OK: Impossible to be both + } + } +} diff --git a/tests/refinements/refinements.exp b/tests/refinements/refinements.exp index 5b99052c014..1494923531e 100644 --- a/tests/refinements/refinements.exp +++ b/tests/refinements/refinements.exp @@ -9330,6 +9330,37 @@ References: ^^^^^^^^^^^^^^^^^^^ [1] +Error -------------------------------------------------------------------------------------------------- mixed.js:135:16 + +Refined at [1] + + mixed.js:135:16 + 135| if (typeof x === 'object') { + ^ + +References: + mixed.js:134:7 + 134| if (typeof x === 'function') { + ^^^^^^^^^^^^^^^^^^^^^^^ [1] + + +Error --------------------------------------------------------------------------------------------------- mixed.js:136:7 + +Refined at [1] [2] + + mixed.js:136:7 + 136| x as empty; // OK: Impossible to be both + ^ + +References: + mixed.js:134:7 + 134| if (typeof x === 'function') { + ^^^^^^^^^^^^^^^^^^^^^^^ [1] + mixed.js:135:9 + 135| if (typeof x === 'object') { + ^^^^^^^^^^^^^^^^^^^^^ [2] + + Error --------------------------------------------------------------------------------------------- mixed_object.js:2:32 Refined at [1] @@ -17001,7 +17032,7 @@ References: -Found 1155 errors +Found 1157 errors Only showing the most relevant union/intersection branches. To see all branches, re-run Flow with --show-all-branches