From 3be862c93312ab643c18dd5fc25b694ce49d2f40 Mon Sep 17 00:00:00 2001 From: Naman Goel Date: Thu, 20 Feb 2025 19:09:37 -0800 Subject: [PATCH] [flow] type refinement for Array.includes Summary: It is a common pattern to use `[a, b, c].includes(foo)` instead of `foo === a || foo === b || foo === c`, but today only the second pattern be used for type refinement. Reviewed By: panagosg7 Differential Revision: D69577322 fbshipit-source-id: 88192132af64e63a6c5ee07104d61b9cf6d3bbe6 --- lib/core.js | 2 +- tests/arrays/includes.js | 5 +++++ tests/autocomplete_from_h_to_l/autocomplete_from_h_to_l.exp | 4 ++-- 3 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 tests/arrays/includes.js diff --git a/lib/core.js b/lib/core.js index 465a6cd4850..4e3534e4af9 100644 --- a/lib/core.js +++ b/lib/core.js @@ -796,7 +796,7 @@ declare class $ReadOnlyArray<+T> { * @param searchElement The element to search for. * @param fromIndex The position in this array at which to begin searching for searchElement. */ - includes(searchElement: mixed, fromIndex?: number): boolean; + includes(searchElement: mixed, fromIndex?: number): implies searchElement is T; /** * Returns the index of the first occurrence of a value in an array. * @param searchElement The value to locate in the array. diff --git a/tests/arrays/includes.js b/tests/arrays/includes.js new file mode 100644 index 00000000000..b95b438d037 --- /dev/null +++ b/tests/arrays/includes.js @@ -0,0 +1,5 @@ +declare var x: number; + +if (([1, 2, 3] as $ReadOnlyArray<1 | 2 | 3>).includes(x)) { + (x as 1 | 2 | 3); +} diff --git a/tests/autocomplete_from_h_to_l/autocomplete_from_h_to_l.exp b/tests/autocomplete_from_h_to_l/autocomplete_from_h_to_l.exp index 2f98929a08b..de53439c9c9 100644 --- a/tests/autocomplete_from_h_to_l/autocomplete_from_h_to_l.exp +++ b/tests/autocomplete_from_h_to_l/autocomplete_from_h_to_l.exp @@ -2391,7 +2391,7 @@ Flags: --pretty }, { "name":"?.includes", - "type":"void | ((searchElement: mixed, fromIndex?: number) => boolean)" + "type":"void | ((searchElement: mixed, fromIndex?: number) => implies searchElement is T)" }, { "name":"?.indexOf", @@ -2500,7 +2500,7 @@ Flags: --pretty }, { "name":"includes", - "type":"(searchElement: mixed, fromIndex?: number) => boolean" + "type":"(searchElement: mixed, fromIndex?: number) => implies searchElement is T" }, { "name":"indexOf",