From 8aeb06fc6dd5c97951560fa028a2e73c092f87b6 Mon Sep 17 00:00:00 2001 From: George Zahariev Date: Fri, 3 Jan 2025 08:04:35 -0800 Subject: [PATCH] [flow][docs] Add docs for `in` refinement Summary: Add docs for `in` refinement. Changelog: [internal] Reviewed By: SamChou19815 Differential Revision: D67775999 fbshipit-source-id: b4f31a59a1ac716eb2691bc721d97924f9a45969 --- website/docs/lang/refinements.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/website/docs/lang/refinements.md b/website/docs/lang/refinements.md index 1c198209a9f..7fc68da7613 100644 --- a/website/docs/lang/refinements.md +++ b/website/docs/lang/refinements.md @@ -164,6 +164,30 @@ function func(value: ?string) { } ``` +### `in` checks + +You can use the [in](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in) +operator to check if a property exists on an object (either in its own properties, or up the prototype chain). +This can be used to refine a union of objects: + +```js flow-check +function func(obj: {foo: string, value: boolean} | {bar: string, value: number}) { + if ('foo' in obj) { + obj.value as boolean; // Works! + } else { + obj.value as number; // Works! + } +} +``` + +This works best on unions of [exact objects](../../types/objects/#exact-and-inexact-object-types), since in the negation we know the property does not exist. +We cannot say the same for [inexact objects](../../types/objects/#exact-and-inexact-object-types), [interfaces](../../types/interfaces/), and [instance types](../../types/classes/), +since they may have other unknown properties, including the one we are checking. +Additionally, [optional properties](../../types/objects/#toc-optional-object-type-properties) may or may not exist, so are not particularly useful to check against. + +If you want to refine a union of [tuple types](../../types/tuples/) based on whether an element exists, +check the [length](../../types/tuples/#length-refinement) property instead of attempted to use `in`. + ### `instanceof` checks You can use the [instanceof](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof) operator to narrow a value as well.