From 97e798a4ca69564f86cfbb0f62f00b1a3ae4b627 Mon Sep 17 00:00:00 2001 From: Panos Vekris Date: Thu, 25 Apr 2024 19:35:26 -0700 Subject: [PATCH] [flow][ast] add one-sided (`implies`) type guard variant Summary: We will be adding a qualifier to type guard definition to express the notion of a "one-sided" refinement (see [relevant TS issue](https://github.com/microsoft/TypeScript/issues/15048)). The new syntax will be: ``` function foo(x: T): implies x is R { ... } ``` A one-sided type guard will only refine the then-branch of a conditional. We are adding this feature to unblock stricter [consistency checking](https://flow.org/en/docs/types/type-guards/#predicate-type-is-consistent-with-refined-type) for the else case of default type guards (two-sided). One-sided type guards continue to have the existing consistency checking. See this exchange for more context: https://twitter.com/danvdk/status/1765745099554668830. This diff adds AST support. Changelog: [internal] Reviewed By: SamChou19815 Differential Revision: D56506513 fbshipit-source-id: fb2adb11ca184bbf983973fa4d7369c5aa5f7cdb --- src/parser/estree_translator.ml | 1 + src/parser/flow_ast.ml | 1 + src/parser_utils/output/js_layout_generator.ml | 1 + src/typing/errors/flow_intermediate_error.ml | 1 + 4 files changed, 4 insertions(+) diff --git a/src/parser/estree_translator.ml b/src/parser/estree_translator.ml index cdd4eab75a2..28e36b2b251 100644 --- a/src/parser/estree_translator.ml +++ b/src/parser/estree_translator.ml @@ -1643,6 +1643,7 @@ with type t = Impl.t = struct match kind with | Default -> null | Asserts -> string "asserts" + | Implies -> string "implies" in node ?comments:(format_internal_comments comments) diff --git a/src/parser/flow_ast.ml b/src/parser/flow_ast.ml index da3c0efff4f..6376b6b4994 100644 --- a/src/parser/flow_ast.ml +++ b/src/parser/flow_ast.ml @@ -670,6 +670,7 @@ and Type : sig and kind = | Default | Asserts + | Implies and ('M, 'T) t' = { kind: kind; diff --git a/src/parser_utils/output/js_layout_generator.ml b/src/parser_utils/output/js_layout_generator.ml index 62d06c875c9..5977cd3cc02 100644 --- a/src/parser_utils/output/js_layout_generator.ml +++ b/src/parser_utils/output/js_layout_generator.ml @@ -3571,6 +3571,7 @@ and type_guard ~opts ~needs_parens guard = match kind with | Default -> [] | Asserts -> [Atom "asserts"] + | Implies -> [Atom "implies"] in let id_part = identifier x in let type_part = diff --git a/src/typing/errors/flow_intermediate_error.ml b/src/typing/errors/flow_intermediate_error.ml index 08b4db535d2..1c2514cd3c0 100644 --- a/src/typing/errors/flow_intermediate_error.ml +++ b/src/typing/errors/flow_intermediate_error.ml @@ -3828,6 +3828,7 @@ let to_printable_error : match kind with | Flow_ast.Type.TypeGuard.Default -> "This kind of type guard is" | Flow_ast.Type.TypeGuard.Asserts -> "Type guard assertions are" + | Flow_ast.Type.TypeGuard.Implies -> "One-sided type guards are" in [text (kind_str ^ " not yet supported.")] | MessageUnsupportedSyntax (UnsupportedInternalSlot { name; static = false }) ->