From a06459296d128719328a18d3d8e4fa544b467e76 Mon Sep 17 00:00:00 2001 From: Christoph Knittel Date: Tue, 27 Oct 2026 12:40:35 +0000 Subject: [PATCH 1/3] Print types from applied functors in created interfaces Why: Create interface copied each type declaration from the source file at the declaration's location. A type of an applied functor or of an included module is located in the functor's body, possibly in another file, so the interface got the unsubstituted body type or whatever lines of the current file happened to be there. Types declared elsewhere are now printed from the signature. Diagnostic modified (create interface): Example: module StrSet = CreateInterfaceFunctor.MakeSet({ type t = string let compare = (a: string, b) => a < b ? -1 : a > b ? 1 : 0 }) Before (rescript): tests/analysis_tests/tests/src/CreateInterfaceFunctorUse.res module StrSet: { let add: (t, string) => array } After (rescript): tests/analysis_tests/tests/src/CreateInterfaceFunctorUse.res module StrSet: { type t = array let add: (t, string) => array } Review: Are types declared in the module itself still copied verbatim? Yes. A type is copied when its location is in the source file and, inside a nested module, within that module's declaration, so attributes on local declarations are kept as before. Fixes: #9065 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Kbf3gLMawVgtmiKy3TMBc3 Signed-off-by: Christoph Knittel --- analysis/src/cli.ml | 2 +- analysis/src/create_interface.ml | 70 ++++++++++++------- changes/create-interface-functor-types.fix.md | 1 + .../tests/src/CreateInterfaceFunctor.res | 16 +++++ .../tests/src/CreateInterfaceFunctorUse.res | 11 +++ .../expected/CreateInterfaceFunctor.res.txt | 17 +++++ .../CreateInterfaceFunctorUse.res.txt | 8 +++ 7 files changed, 99 insertions(+), 26 deletions(-) create mode 100644 changes/create-interface-functor-types.fix.md create mode 100644 tests/analysis_tests/tests/src/CreateInterfaceFunctor.res create mode 100644 tests/analysis_tests/tests/src/CreateInterfaceFunctorUse.res create mode 100644 tests/analysis_tests/tests/src/expected/CreateInterfaceFunctor.res.txt create mode 100644 tests/analysis_tests/tests/src/expected/CreateInterfaceFunctorUse.res.txt diff --git a/analysis/src/cli.ml b/analysis/src/cli.ml index 18299e95d07..82147931c90 100644 --- a/analysis/src/cli.ml +++ b/analysis/src/cli.ml @@ -176,7 +176,7 @@ let create_interface ~path ~cmi_file = match Files.read_file path with | None -> "" | Some source -> ( - match Create_interface.command ~source ~cmi_file with + match Create_interface.command ~path ~source ~cmi_file with | Ok content -> content | Error _ -> "") in diff --git a/analysis/src/create_interface.ml b/analysis/src/create_interface.ml index 9a6e3495377..0fb8de53339 100644 --- a/analysis/src/create_interface.ml +++ b/analysis/src/create_interface.ml @@ -95,7 +95,19 @@ end = struct !res |> List.rev |> String.concat "\n" end -let print_signature ~extractor ~signature = +(* A type declared in the module being printed can be copied from the source. + One that comes from elsewhere, such as the body of an applied functor or an + included module of another file, has its location there instead. *) +let declared_in ~path ~(scope : Location.t option) (loc : Location.t) = + Filename.basename loc.loc_start.pos_fname = Filename.basename path + && + match scope with + | None -> true + | Some scope -> + scope.loc_start.pos_cnum <= loc.loc_start.pos_cnum + && loc.loc_end.pos_cnum <= scope.loc_end.pos_cnum + +let print_signature ~path ~extractor ~signature = Printtyp.reset_names (); let sig_item_to_string (item : Outcometree.out_sig_item) = item |> Res_outcome_printer.print_out_sig_item_doc @@ -140,7 +152,8 @@ let print_signature ~extractor ~signature = | _ -> None in - let rec process_signature ~indent (signature : Types.signature) : unit = + let rec process_signature ~scope ~indent (signature : Types.signature) : unit + = match signature with | Sig_type (props_id, {type_params; type_kind = Type_record (label_decls, _)}, _) @@ -193,7 +206,7 @@ let print_signature ~extractor ~signature = in Buffer.add_string buf (indent ^ "@react.component\n"); Buffer.add_string buf (indent ^ new_item_str ^ "\n"); - process_signature ~indent rest + process_signature ~scope ~indent rest | Sig_module (id, mod_decl, rec_status) :: rest -> let colon_or_equals = match mod_decl.md_type with @@ -207,9 +220,9 @@ let print_signature ~extractor ~signature = | Trec_first -> "module rec " | Trec_next -> "and ") ^ Ident.name id ^ colon_or_equals); - process_module_type ~indent mod_decl.md_type; + process_module_type ~scope:(Some mod_decl.md_loc) ~indent mod_decl.md_type; Buffer.add_string buf "\n"; - process_signature ~indent rest + process_signature ~scope ~indent rest | Sig_modtype (id, mtd) :: rest -> let () = match mtd.mtd_type with @@ -217,10 +230,10 @@ let print_signature ~extractor ~signature = Buffer.add_string buf (indent ^ "module type " ^ Ident.name id ^ "\n") | Some mt -> Buffer.add_string buf (indent ^ "module type " ^ Ident.name id ^ " = "); - process_module_type ~indent mt; + process_module_type ~scope:(Some mtd.mtd_loc) ~indent mt; Buffer.add_string buf "\n" in - process_signature ~indent rest + process_signature ~scope ~indent rest | Sig_value (id, ({val_kind = Val_prim prim; val_loc} as vd)) :: items when prim.prim_kind <> Primitive.Kind_intrinsic -> (* Rescript primitive name, e.g. @val external ... *) @@ -238,34 +251,41 @@ let print_signature ~extractor ~signature = (* Copy the external declaration verbatim from the implementation file *) Buffer.add_string buf ((lines |> String.concat "\n") ^ "\n"); - process_signature ~indent items + process_signature ~scope ~indent items | Sig_value (id, vd) :: items -> let new_item_str = sig_item_to_string (Printtyp.tree_of_value_description id vd) in Buffer.add_string buf (indent ^ new_item_str ^ "\n"); - process_signature ~indent items - | Sig_type (_id, type_decl, _recStatus) :: items -> - let lines = - let pos_start, pos_end = Loc.range type_decl.type_loc in - extractor |> Source_file_extractor.extract ~pos_start ~pos_end - in - (* Copy the type declaration verbatim to preserve attributes *) - Buffer.add_string buf ((lines |> String.concat "\n") ^ "\n"); - process_signature ~indent items + process_signature ~scope ~indent items + | Sig_type (id, type_decl, rec_status) :: items -> + (if declared_in ~path ~scope type_decl.type_loc then + let lines = + let pos_start, pos_end = Loc.range type_decl.type_loc in + extractor |> Source_file_extractor.extract ~pos_start ~pos_end + in + (* Copy the type declaration verbatim to preserve attributes *) + Buffer.add_string buf ((lines |> String.concat "\n") ^ "\n") + else + let new_item_str = + sig_item_to_string + (Printtyp.tree_of_type_declaration id type_decl rec_status) + in + Buffer.add_string buf (indent ^ new_item_str ^ "\n")); + process_signature ~scope ~indent items | Sig_typext (id, ext_constr, ext_status) :: items -> let new_item_str = sig_item_to_string (Printtyp.tree_of_extension_constructor id ext_constr ext_status) in Buffer.add_string buf (indent ^ new_item_str ^ "\n"); - process_signature ~indent items + process_signature ~scope ~indent items | [] -> () - and process_module_type ~indent (mt : Types.module_type) = + and process_module_type ~scope ~indent (mt : Types.module_type) = match mt with | Mty_signature signature -> Buffer.add_string buf "{\n"; - process_signature ~indent:(indent ^ " ") signature; + process_signature ~scope ~indent:(indent ^ " ") signature; Buffer.add_string buf (indent ^ "}") | Mty_functor _ -> let rec collect_functor_args ~args (mt : Types.module_type) = @@ -286,11 +306,11 @@ let print_signature ~extractor ~signature = | None -> Buffer.add_string buf (Ident.name id) | Some mt -> Buffer.add_string buf (Ident.name id ^ ": "); - process_module_type ~indent:(indent ^ " ") mt); + process_module_type ~scope ~indent:(indent ^ " ") mt); Buffer.add_string buf ","); if args <> [] then Buffer.add_string buf ("\n" ^ indent); Buffer.add_string buf (") =>\n" ^ indent); - process_module_type ~indent ret_mt + process_module_type ~scope ~indent ret_mt | Mty_ident path | Mty_alias (_, path) -> let rec out_ident_to_string (ident : Outcometree.out_ident) = match ident with @@ -302,12 +322,12 @@ let print_signature ~extractor ~signature = Buffer.add_string buf (out_ident_to_string (Printtyp.tree_of_path path)) in - process_signature ~indent:"" signature; + process_signature ~scope:None ~indent:"" signature; Buffer.contents buf -let command ~source ~cmi_file = +let command ~path ~source ~cmi_file = match Shared.try_read_cmi cmi_file with | Some cmi_info -> let extractor = source |> String.split_on_char '\n' |> Array.of_list in - Ok (print_signature ~extractor ~signature:cmi_info.cmi_sign) + Ok (print_signature ~path ~extractor ~signature:cmi_info.cmi_sign) | None -> Error ("Failed to read cmi file " ^ cmi_file) diff --git a/changes/create-interface-functor-types.fix.md b/changes/create-interface-functor-types.fix.md new file mode 100644 index 00000000000..5ed2730ed2d --- /dev/null +++ b/changes/create-interface-functor-types.fix.md @@ -0,0 +1 @@ +- Editor "create interface" prints the types of applied functors and included modules instead of copying unrelated source lines. diff --git a/tests/analysis_tests/tests/src/CreateInterfaceFunctor.res b/tests/analysis_tests/tests/src/CreateInterfaceFunctor.res new file mode 100644 index 00000000000..d87b26307ab --- /dev/null +++ b/tests/analysis_tests/tests/src/CreateInterfaceFunctor.res @@ -0,0 +1,16 @@ +// ^int + +module type Ord = { + type t + let compare: (t, t) => int +} + +module MakeSet = (O: Ord) => { + type t = array + let add = (s: t, x: O.t) => s->Array.concat([x]) +} + +module IntSet = MakeSet({ + type t = int + let compare = (a: int, b) => a - b +}) diff --git a/tests/analysis_tests/tests/src/CreateInterfaceFunctorUse.res b/tests/analysis_tests/tests/src/CreateInterfaceFunctorUse.res new file mode 100644 index 00000000000..864922f99dd --- /dev/null +++ b/tests/analysis_tests/tests/src/CreateInterfaceFunctorUse.res @@ -0,0 +1,11 @@ +// ^int + +module StrSet = CreateInterfaceFunctor.MakeSet({ + type t = string + let compare = (a: string, b) => a < b ? -1 : a > b ? 1 : 0 +}) + +include CreateInterfaceFunctor.MakeSet({ + type t = float + let compare = (a: float, b) => a < b ? -1 : a > b ? 1 : 0 +}) diff --git a/tests/analysis_tests/tests/src/expected/CreateInterfaceFunctor.res.txt b/tests/analysis_tests/tests/src/expected/CreateInterfaceFunctor.res.txt new file mode 100644 index 00000000000..d6660fe1b53 --- /dev/null +++ b/tests/analysis_tests/tests/src/expected/CreateInterfaceFunctor.res.txt @@ -0,0 +1,17 @@ +Create Interface src/CreateInterfaceFunctor.res +module type Ord = { + type t + let compare: (t, t) => int +} +module MakeSet: ( + O: Ord, +) => +{ + type t = array + let add: (t, O.t) => array +} +module IntSet: { + type t = array + let add: (t, int) => array +} + diff --git a/tests/analysis_tests/tests/src/expected/CreateInterfaceFunctorUse.res.txt b/tests/analysis_tests/tests/src/expected/CreateInterfaceFunctorUse.res.txt new file mode 100644 index 00000000000..4f61a6e2f57 --- /dev/null +++ b/tests/analysis_tests/tests/src/expected/CreateInterfaceFunctorUse.res.txt @@ -0,0 +1,8 @@ +Create Interface src/CreateInterfaceFunctorUse.res +module StrSet: { + type t = array + let add: (t, string) => array +} +type t = array +let add: (t, float) => array + From de88a9c01d16088f3f4ab6c0a40dbe11003f24e5 Mon Sep 17 00:00:00 2001 From: Christoph Knittel Date: Tue, 27 Oct 2026 17:33:42 +0000 Subject: [PATCH 2/3] Copy same-file types outside functors verbatim in created interfaces Codex review on #9077: a type of the same file reached through `module type of` or `include` was printed from the signature, which drops field attributes such as `@as`, so the interface no longer matched. Only types inside a functor body other than the module being printed, and types of other files, are printed from the signature now. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Kbf3gLMawVgtmiKy3TMBc3 Signed-off-by: Christoph Knittel --- analysis/src/create_interface.ml | 36 ++++++++++++++----- .../tests/src/CreateInterfaceFunctor.res | 11 ++++++ .../expected/CreateInterfaceFunctor.res.txt | 9 +++++ 3 files changed, 47 insertions(+), 9 deletions(-) diff --git a/analysis/src/create_interface.ml b/analysis/src/create_interface.ml index 0fb8de53339..a2bf3a268f1 100644 --- a/analysis/src/create_interface.ml +++ b/analysis/src/create_interface.ml @@ -95,20 +95,38 @@ end = struct !res |> List.rev |> String.concat "\n" end -(* A type declared in the module being printed can be copied from the source. - One that comes from elsewhere, such as the body of an applied functor or an - included module of another file, has its location there instead. *) -let declared_in ~path ~(scope : Location.t option) (loc : Location.t) = +let loc_within ~(outer : Location.t) (loc : Location.t) = + outer.loc_start.pos_cnum <= loc.loc_start.pos_cnum + && loc.loc_end.pos_cnum <= outer.loc_end.pos_cnum + +(* The locations of the functors in a signature, nested ones included. *) +let rec functor_locs (signature : Types.signature) = + signature + |> List.concat_map (function + | Types.Sig_module (_, {md_type; md_loc}, _) -> ( + match md_type with + | Mty_functor _ -> [md_loc] + | Mty_signature signature -> functor_locs signature + | Mty_ident _ | Mty_alias _ -> []) + | _ -> []) + +(* The source text of a type declaration can be copied when it says what the + type is at this point of the interface: when the type is declared in this + file, and either inside the module being printed or outside any functor. + A type of an applied functor is located in the functor's body, where its + definition mentions the functor's parameters, and a type included from + another file is located there; both are printed from the signature. *) +let declared_in ~path ~functors ~(scope : Location.t option) (loc : Location.t) + = Filename.basename loc.loc_start.pos_fname = Filename.basename path && match scope with - | None -> true - | Some scope -> - scope.loc_start.pos_cnum <= loc.loc_start.pos_cnum - && loc.loc_end.pos_cnum <= scope.loc_end.pos_cnum + | Some scope when loc_within ~outer:scope loc -> true + | _ -> not (List.exists (fun outer -> loc_within ~outer loc) functors) let print_signature ~path ~extractor ~signature = Printtyp.reset_names (); + let functors = functor_locs signature in let sig_item_to_string (item : Outcometree.out_sig_item) = item |> Res_outcome_printer.print_out_sig_item_doc |> Res_doc.to_string ~width:Res_printer.default_print_width @@ -259,7 +277,7 @@ let print_signature ~path ~extractor ~signature = Buffer.add_string buf (indent ^ new_item_str ^ "\n"); process_signature ~scope ~indent items | Sig_type (id, type_decl, rec_status) :: items -> - (if declared_in ~path ~scope type_decl.type_loc then + (if declared_in ~path ~functors ~scope type_decl.type_loc then let lines = let pos_start, pos_end = Loc.range type_decl.type_loc in extractor |> Source_file_extractor.extract ~pos_start ~pos_end diff --git a/tests/analysis_tests/tests/src/CreateInterfaceFunctor.res b/tests/analysis_tests/tests/src/CreateInterfaceFunctor.res index d87b26307ab..1998bf1431d 100644 --- a/tests/analysis_tests/tests/src/CreateInterfaceFunctor.res +++ b/tests/analysis_tests/tests/src/CreateInterfaceFunctor.res @@ -14,3 +14,14 @@ module IntSet = MakeSet({ type t = int let compare = (a: int, b) => a - b }) + +// Types of the same file outside a functor keep their attributes +module M = { + type t = {@as("wire") field: int} +} + +module type S = module type of M + +module N = { + include M +} diff --git a/tests/analysis_tests/tests/src/expected/CreateInterfaceFunctor.res.txt b/tests/analysis_tests/tests/src/expected/CreateInterfaceFunctor.res.txt index d6660fe1b53..1e6f4877f5c 100644 --- a/tests/analysis_tests/tests/src/expected/CreateInterfaceFunctor.res.txt +++ b/tests/analysis_tests/tests/src/expected/CreateInterfaceFunctor.res.txt @@ -14,4 +14,13 @@ module IntSet: { type t = array let add: (t, int) => array } +module M: { + type t = {@as("wire") field: int} +} +module type S = { + type t = {@as("wire") field: int} +} +module N: { + type t = {@as("wire") field: int} +} From 8a9ddb546aa1f81ddb6ce7d9e2f58ffac26e819b Mon Sep 17 00:00:00 2001 From: Christoph Knittel Date: Wed, 28 Oct 2026 07:39:39 +0000 Subject: [PATCH 3/3] Print the runtime names of record fields from signatures Review on #9077: a type of an applied functor is printed from its signature, and the printed record dropped `@as` on its fields, so the created interface for `module M = F({})` with `type t = {@as("wire") field: int}` in F's body didn't match. Record fields in the outcome tree now carry their runtime name, and the printer writes it as `@as`, which also shows it in hover and error messages. Diagnostic modified (created interface of an applied functor): Example: module WithWire = (X: {}) => { type t = {@as("wire") field: int} } module Applied = WithWire({}) Before (rescript): module Applied: { type t = {field: int} } After (rescript): module Applied: { type t = {@as("wire") field: int} } Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Kbf3gLMawVgtmiKy3TMBc3 Signed-off-by: Christoph Knittel --- compiler/ml/outcometree.ml | 3 ++- compiler/ml/printtyp.ml | 1 + compiler/syntax/src/res_outcome_printer.ml | 6 +++++- .../tests/src/CreateInterfaceFunctor.res | 7 +++++++ .../tests/src/expected/Completion.res.txt | 2 +- .../tests/src/expected/CreateInterfaceFunctor.res.txt | 10 ++++++++++ 6 files changed, 26 insertions(+), 3 deletions(-) diff --git a/compiler/ml/outcometree.ml b/compiler/ml/outcometree.ml index 42de661ead9..6e011c356f8 100644 --- a/compiler/ml/outcometree.ml +++ b/compiler/ml/outcometree.ml @@ -37,7 +37,8 @@ type out_type = | Otyp_manifest of out_type * out_type | Otyp_object of (string * bool * out_type) list * bool option (* fields are (name, mutable, type) *) - | Otyp_record of (string * bool * bool * out_type) list + | Otyp_record of (string * string option * bool * bool * out_type) list + (** name, runtime name given with [@as], mutable, optional, type *) | Otyp_stuff of string | Otyp_sum of (string * out_type list * out_type option * string option) list | Otyp_tuple of out_type list diff --git a/compiler/ml/printtyp.ml b/compiler/ml/printtyp.ml index d3153fa3e10..69e77c2d17a 100644 --- a/compiler/ml/printtyp.ml +++ b/compiler/ml/printtyp.ml @@ -951,6 +951,7 @@ and tree_of_label ?printing_context l = | _ -> l.ld_type in ( Ident.name l.ld_id, + l.ld_runtime_name, l.ld_mutable = Mutable, opt, tree_of_typexp ?printing_context false typ ) diff --git a/compiler/syntax/src/res_outcome_printer.ml b/compiler/syntax/src/res_outcome_printer.ml index cabef35d205..8dca31da6b1 100644 --- a/compiler/syntax/src/res_outcome_printer.ml +++ b/compiler/syntax/src/res_outcome_printer.ml @@ -392,10 +392,14 @@ and print_out_constructor_doc (name, args, gadt, repr) = in Doc.group (Doc.concat [repr_doc; Doc.text name; args_doc; gadt_doc]) -and print_record_decl_row_doc (name, mut, opt, arg) = +and print_record_decl_row_doc (name, runtime_name, mut, opt, arg) = Doc.group (Doc.concat [ + (match runtime_name with + | Some runtime_name -> + Doc.text ("@as(\"" ^ String.escaped runtime_name ^ "\") ") + | None -> Doc.nil); (if mut then Doc.text "mutable " else Doc.nil); Printer.print_ident_like ~allow_uident:false name; (if opt then Doc.text "?" else Doc.nil); diff --git a/tests/analysis_tests/tests/src/CreateInterfaceFunctor.res b/tests/analysis_tests/tests/src/CreateInterfaceFunctor.res index 1998bf1431d..c1374f2fd85 100644 --- a/tests/analysis_tests/tests/src/CreateInterfaceFunctor.res +++ b/tests/analysis_tests/tests/src/CreateInterfaceFunctor.res @@ -25,3 +25,10 @@ module type S = module type of M module N = { include M } + +// Types of an applied functor keep the runtime names of their fields +module WithWire = (X: {}) => { + type t = {@as("wire") field: int} +} + +module Applied = WithWire({}) diff --git a/tests/analysis_tests/tests/src/expected/Completion.res.txt b/tests/analysis_tests/tests/src/expected/Completion.res.txt index 446bdac5984..7a6e3a8a493 100644 --- a/tests/analysis_tests/tests/src/expected/Completion.res.txt +++ b/tests/analysis_tests/tests/src/expected/Completion.res.txt @@ -2371,7 +2371,7 @@ Hover src/Completion.res 349:14 { "contents": { "kind": "markdown", - "value": "```rescript\nJsxDOM.domProps\n```\n\n---\n\n```\n \n```\n```rescript\ntype JsxDOM.domProps = {\n key?: string,\n children?: Jsx.element,\n ref?: domRef,\n allow?: string,\n ariaCurrent?: [\n | #date\n | #\"false\"\n | #location\n | #page\n | #step\n | #time\n | #\"true\"\n ],\n ariaDetails?: string,\n ariaDisabled?: bool,\n ariaHidden?: bool,\n ariaInvalid?: [#\"false\" | #grammar | #spelling | #\"true\"],\n ariaKeyshortcuts?: string,\n ariaLabel?: string,\n ariaRoledescription?: string,\n ariaAutocomplete?: [#both | #inline | #list | #none],\n ariaChecked?: [#\"false\" | #mixed | #\"true\"],\n ariaExpanded?: bool,\n ariaHaspopup?: [\n | #dialog\n | #\"false\"\n | #grid\n | #listbox\n | #menu\n | #tree\n | #\"true\"\n ],\n ariaLevel?: int,\n ariaModal?: bool,\n ariaMultiline?: bool,\n ariaMultiselectable?: bool,\n ariaOrientation?: [#horizontal | #undefined | #vertical],\n ariaPlaceholder?: string,\n ariaPressed?: [#\"false\" | #mixed | #\"true\"],\n ariaReadonly?: bool,\n ariaRequired?: bool,\n ariaSelected?: bool,\n ariaSort?: string,\n ariaValuemax?: float,\n ariaValuemin?: float,\n ariaValuenow?: float,\n ariaValuetext?: string,\n ariaAtomic?: bool,\n ariaBusy?: bool,\n ariaLive?: [#assertive | #off | #polite | #rude],\n ariaRelevant?: string,\n ariaDropeffect?: [\n | #copy\n | #execute\n | #link\n | #move\n | #none\n | #popup\n ],\n ariaGrabbed?: bool,\n ariaActivedescendant?: string,\n ariaColcount?: int,\n ariaColindex?: int,\n ariaColspan?: int,\n ariaControls?: string,\n ariaDescribedby?: string,\n ariaErrormessage?: string,\n ariaFlowto?: string,\n ariaLabelledby?: string,\n ariaOwns?: string,\n ariaPosinset?: int,\n ariaRowcount?: int,\n ariaRowindex?: int,\n ariaRowspan?: int,\n ariaSetsize?: int,\n defaultChecked?: bool,\n defaultValue?: string,\n accessKey?: string,\n capture?: [#environment | #user],\n className?: string,\n contentEditable?: bool,\n contextMenu?: string,\n dataTestId?: string,\n dir?: string,\n draggable?: bool,\n hidden?: bool,\n id?: string,\n inert?: bool,\n lang?: string,\n popover?: popover,\n popoverTarget?: string,\n popoverTargetAction?: popoverTargetAction,\n role?: string,\n style?: style,\n spellCheck?: bool,\n tabIndex?: int,\n title?: string,\n itemID?: string,\n itemProp?: string,\n itemRef?: string,\n itemScope?: bool,\n itemType?: string,\n accept?: string,\n acceptCharset?: string,\n action?: string,\n allowFullScreen?: bool,\n alt?: string,\n as_?: string,\n async?: bool,\n autoComplete?: string,\n autoCapitalize?: string,\n autoFocus?: bool,\n autoPlay?: bool,\n challenge?: string,\n charSet?: string,\n checked?: bool,\n cite?: string,\n crossOrigin?: string,\n cols?: int,\n colSpan?: int,\n content?: string,\n controls?: bool,\n coords?: string,\n data?: string,\n dateTime?: string,\n default?: bool,\n defer?: bool,\n disabled?: bool,\n download?: string,\n encType?: string,\n form?: string,\n formAction?: string,\n formTarget?: string,\n formMethod?: string,\n frameBorder?: int,\n headers?: string,\n height?: string,\n high?: int,\n href?: string,\n hrefLang?: string,\n htmlFor?: string,\n httpEquiv?: string,\n icon?: string,\n inputMode?: string,\n integrity?: string,\n keyType?: string,\n kind?: string,\n label?: string,\n list?: string,\n loading?: [#eager | #lazy],\n loop?: bool,\n low?: int,\n manifest?: string,\n max?: string,\n maxLength?: int,\n media?: string,\n mediaGroup?: string,\n method?: string,\n min?: string,\n minLength?: int,\n multiple?: bool,\n muted?: bool,\n name?: string,\n nonce?: string,\n noValidate?: bool,\n open_?: bool,\n optimum?: int,\n pattern?: string,\n placeholder?: string,\n playsInline?: bool,\n poster?: string,\n preload?: string,\n radioGroup?: string,\n readOnly?: bool,\n rel?: string,\n required?: bool,\n reversed?: bool,\n rows?: int,\n rowSpan?: int,\n sandbox?: string,\n scope?: string,\n scoped?: bool,\n scrolling?: string,\n selected?: bool,\n shape?: string,\n size?: int,\n sizes?: string,\n span?: int,\n src?: string,\n srcDoc?: string,\n srcLang?: string,\n srcSet?: string,\n start?: int,\n step?: float,\n summary?: string,\n target?: string,\n type_?: string,\n useMap?: string,\n value?: string,\n width?: string,\n wrap?: string,\n onCopy?: JsxEvent.Clipboard.t => unit,\n onCut?: JsxEvent.Clipboard.t => unit,\n onPaste?: JsxEvent.Clipboard.t => unit,\n onCompositionEnd?: JsxEvent.Composition.t => unit,\n onCompositionStart?: JsxEvent.Composition.t => unit,\n onCompositionUpdate?: JsxEvent.Composition.t => unit,\n onKeyDown?: JsxEvent.Keyboard.t => unit,\n onKeyPress?: JsxEvent.Keyboard.t => unit,\n onKeyUp?: JsxEvent.Keyboard.t => unit,\n onFocus?: JsxEvent.Focus.t => unit,\n onBlur?: JsxEvent.Focus.t => unit,\n onBeforeInput?: JsxEvent.Form.t => unit,\n onChange?: JsxEvent.Form.t => unit,\n onInput?: JsxEvent.Form.t => unit,\n onReset?: JsxEvent.Form.t => unit,\n onSubmit?: JsxEvent.Form.t => unit,\n onInvalid?: JsxEvent.Form.t => unit,\n onClick?: JsxEvent.Mouse.t => unit,\n onContextMenu?: JsxEvent.Mouse.t => unit,\n onDoubleClick?: JsxEvent.Mouse.t => unit,\n onDrag?: JsxEvent.Mouse.t => unit,\n onDragEnd?: JsxEvent.Mouse.t => unit,\n onDragEnter?: JsxEvent.Mouse.t => unit,\n onDragExit?: JsxEvent.Mouse.t => unit,\n onDragLeave?: JsxEvent.Mouse.t => unit,\n onDragOver?: JsxEvent.Mouse.t => unit,\n onDragStart?: JsxEvent.Mouse.t => unit,\n onDrop?: JsxEvent.Mouse.t => unit,\n onMouseDown?: JsxEvent.Mouse.t => unit,\n onMouseEnter?: JsxEvent.Mouse.t => unit,\n onMouseLeave?: JsxEvent.Mouse.t => unit,\n onMouseMove?: JsxEvent.Mouse.t => unit,\n onMouseOut?: JsxEvent.Mouse.t => unit,\n onMouseOver?: JsxEvent.Mouse.t => unit,\n onMouseUp?: JsxEvent.Mouse.t => unit,\n onSelect?: JsxEvent.Selection.t => unit,\n onTouchCancel?: JsxEvent.Touch.t => unit,\n onTouchEnd?: JsxEvent.Touch.t => unit,\n onTouchMove?: JsxEvent.Touch.t => unit,\n onTouchStart?: JsxEvent.Touch.t => unit,\n onPointerOver?: JsxEvent.Pointer.t => unit,\n onPointerEnter?: JsxEvent.Pointer.t => unit,\n onPointerDown?: JsxEvent.Pointer.t => unit,\n onPointerMove?: JsxEvent.Pointer.t => unit,\n onPointerUp?: JsxEvent.Pointer.t => unit,\n onPointerCancel?: JsxEvent.Pointer.t => unit,\n onPointerOut?: JsxEvent.Pointer.t => unit,\n onPointerLeave?: JsxEvent.Pointer.t => unit,\n onGotPointerCapture?: JsxEvent.Pointer.t => unit,\n onLostPointerCapture?: JsxEvent.Pointer.t => unit,\n onScroll?: JsxEvent.UI.t => unit,\n onWheel?: JsxEvent.Wheel.t => unit,\n onAbort?: JsxEvent.Media.t => unit,\n onCanPlay?: JsxEvent.Media.t => unit,\n onCanPlayThrough?: JsxEvent.Media.t => unit,\n onDurationChange?: JsxEvent.Media.t => unit,\n onEmptied?: JsxEvent.Media.t => unit,\n onEncrypted?: JsxEvent.Media.t => unit,\n onEnded?: JsxEvent.Media.t => unit,\n onError?: JsxEvent.Media.t => unit,\n onLoadedData?: JsxEvent.Media.t => unit,\n onLoadedMetadata?: JsxEvent.Media.t => unit,\n onLoadStart?: JsxEvent.Media.t => unit,\n onPause?: JsxEvent.Media.t => unit,\n onPlay?: JsxEvent.Media.t => unit,\n onPlaying?: JsxEvent.Media.t => unit,\n onProgress?: JsxEvent.Media.t => unit,\n onRateChange?: JsxEvent.Media.t => unit,\n onSeeked?: JsxEvent.Media.t => unit,\n onSeeking?: JsxEvent.Media.t => unit,\n onStalled?: JsxEvent.Media.t => unit,\n onSuspend?: JsxEvent.Media.t => unit,\n onTimeUpdate?: JsxEvent.Media.t => unit,\n onVolumeChange?: JsxEvent.Media.t => unit,\n onWaiting?: JsxEvent.Media.t => unit,\n onLoad?: JsxEvent.Image.t => unit,\n onAnimationStart?: JsxEvent.Animation.t => unit,\n onAnimationEnd?: JsxEvent.Animation.t => unit,\n onAnimationIteration?: JsxEvent.Animation.t => unit,\n onTransitionEnd?: JsxEvent.Transition.t => unit,\n accentHeight?: string,\n accumulate?: string,\n additive?: string,\n alignmentBaseline?: string,\n allowReorder?: string,\n alphabetic?: string,\n amplitude?: string,\n arabicForm?: string,\n ascent?: string,\n attributeName?: string,\n attributeType?: string,\n autoReverse?: string,\n azimuth?: string,\n baseFrequency?: string,\n baseProfile?: string,\n baselineShift?: string,\n bbox?: string,\n begin?: string,\n bias?: string,\n by?: string,\n calcMode?: string,\n capHeight?: string,\n clip?: string,\n clipPath?: string,\n clipPathUnits?: string,\n clipRule?: string,\n colorInterpolation?: string,\n colorInterpolationFilters?: string,\n colorProfile?: string,\n colorRendering?: string,\n contentScriptType?: string,\n contentStyleType?: string,\n cursor?: string,\n cx?: string,\n cy?: string,\n d?: string,\n decelerate?: string,\n descent?: string,\n diffuseConstant?: string,\n direction?: string,\n display?: string,\n divisor?: string,\n dominantBaseline?: string,\n dur?: string,\n dx?: string,\n dy?: string,\n edgeMode?: string,\n elevation?: string,\n enableBackground?: string,\n end?: string,\n exponent?: string,\n externalResourcesRequired?: string,\n fill?: string,\n fillOpacity?: string,\n fillRule?: string,\n filter?: string,\n filterRes?: string,\n filterUnits?: string,\n floodColor?: string,\n floodOpacity?: string,\n focusable?: string,\n fontFamily?: string,\n fontSize?: string,\n fontSizeAdjust?: string,\n fontStretch?: string,\n fontStyle?: string,\n fontVariant?: string,\n fontWeight?: string,\n fomat?: string,\n from?: string,\n fx?: string,\n fy?: string,\n g1?: string,\n g2?: string,\n glyphName?: string,\n glyphOrientationHorizontal?: string,\n glyphOrientationVertical?: string,\n glyphRef?: string,\n gradientTransform?: string,\n gradientUnits?: string,\n hanging?: string,\n horizAdvX?: string,\n horizOriginX?: string,\n ideographic?: string,\n imageRendering?: string,\n in_?: string,\n in2?: string,\n intercept?: string,\n k?: string,\n k1?: string,\n k2?: string,\n k3?: string,\n k4?: string,\n kernelMatrix?: string,\n kernelUnitLength?: string,\n kerning?: string,\n keyPoints?: string,\n keySplines?: string,\n keyTimes?: string,\n lengthAdjust?: string,\n letterSpacing?: string,\n lightingColor?: string,\n limitingConeAngle?: string,\n local?: string,\n markerEnd?: string,\n markerHeight?: string,\n markerMid?: string,\n markerStart?: string,\n markerUnits?: string,\n markerWidth?: string,\n mask?: string,\n maskContentUnits?: string,\n maskUnits?: string,\n mathematical?: string,\n mode?: string,\n numOctaves?: string,\n offset?: string,\n opacity?: string,\n operator?: string,\n order?: string,\n orient?: string,\n orientation?: string,\n origin?: string,\n overflow?: string,\n overflowX?: string,\n overflowY?: string,\n overlinePosition?: string,\n overlineThickness?: string,\n paintOrder?: string,\n panose1?: string,\n pathLength?: string,\n patternContentUnits?: string,\n patternTransform?: string,\n patternUnits?: string,\n pointerEvents?: string,\n points?: string,\n pointsAtX?: string,\n pointsAtY?: string,\n pointsAtZ?: string,\n preserveAlpha?: string,\n preserveAspectRatio?: string,\n primitiveUnits?: string,\n r?: string,\n radius?: string,\n referrerPolicy?: string,\n refX?: string,\n refY?: string,\n renderingIntent?: string,\n repeatCount?: string,\n repeatDur?: string,\n requiredExtensions?: string,\n requiredFeatures?: string,\n restart?: string,\n result?: string,\n rotate?: string,\n rx?: string,\n ry?: string,\n scale?: string,\n seed?: string,\n shapeRendering?: string,\n slope?: string,\n slot?: string,\n spacing?: string,\n specularConstant?: string,\n specularExponent?: string,\n speed?: string,\n spreadMethod?: string,\n startOffset?: string,\n stdDeviation?: string,\n stemh?: string,\n stemv?: string,\n stitchTiles?: string,\n stopColor?: string,\n stopOpacity?: string,\n strikethroughPosition?: string,\n strikethroughThickness?: string,\n string?: string,\n stroke?: string,\n strokeDasharray?: string,\n strokeDashoffset?: string,\n strokeLinecap?: string,\n strokeLinejoin?: string,\n strokeMiterlimit?: string,\n strokeOpacity?: string,\n strokeWidth?: string,\n surfaceScale?: string,\n systemLanguage?: string,\n tableValues?: string,\n targetX?: string,\n targetY?: string,\n textAnchor?: string,\n textDecoration?: string,\n textLength?: string,\n textRendering?: string,\n to?: string,\n transform?: string,\n u1?: string,\n u2?: string,\n underlinePosition?: string,\n underlineThickness?: string,\n unicode?: string,\n unicodeBidi?: string,\n unicodeRange?: string,\n unitsPerEm?: string,\n vAlphabetic?: string,\n vHanging?: string,\n vIdeographic?: string,\n vMathematical?: string,\n values?: string,\n vectorEffect?: string,\n version?: string,\n vertAdvX?: string,\n vertAdvY?: string,\n vertOriginX?: string,\n vertOriginY?: string,\n viewBox?: string,\n viewTarget?: string,\n visibility?: string,\n widths?: string,\n wordSpacing?: string,\n writingMode?: string,\n x?: string,\n x1?: string,\n x2?: string,\n xChannelSelector?: string,\n xHeight?: string,\n xlinkActuate?: string,\n xlinkArcrole?: string,\n xlinkHref?: string,\n xlinkRole?: string,\n xlinkShow?: string,\n xlinkTitle?: string,\n xlinkType?: string,\n xmlns?: string,\n xmlnsXlink?: string,\n xmlBase?: string,\n xmlLang?: string,\n xmlSpace?: string,\n y?: string,\n y1?: string,\n y2?: string,\n yChannelSelector?: string,\n z?: string,\n zoomAndPan?: string,\n about?: string,\n datatype?: string,\n inlist?: string,\n prefix?: string,\n property?: string,\n resource?: string,\n typeof?: string,\n vocab?: string,\n dangerouslySetInnerHTML?: {\"__html\": string},\n suppressContentEditableWarning?: bool,\n}\n```\nGo to: [Type definition](JsxDOM.res#L21,1)\n\n\n---\n\n```\n \n```\n```rescript\ntype Jsx.element\n```\nGo to: [Type definition](Jsx.res#L8,1)\n\n\n---\n\n```\n \n```\n```rescript\ntype domRef\n```\nGo to: [Type definition](JsxDOM.res#L8,1)\n\n\n---\n\n```\n \n```\n```rescript\ntype popover =\n | @as(\"auto\") Auto\n | @as(\"manual\") Manual\n | @as(\"hint\") Hint\n```\nGo to: [Type definition](JsxDOM.res#L12,1)\n\n\n---\n\n```\n \n```\n```rescript\ntype popoverTargetAction =\n | @as(\"toggle\") Toggle\n | @as(\"show\") Show\n | @as(\"hide\") Hide\n```\nGo to: [Type definition](JsxDOM.res#L16,1)\n\n\n---\n\n```\n \n```\n```rescript\ntype style = JsxDOMStyle.t\n```\nGo to: [Type definition](JsxDOM.res#L7,1)\n\n\n---\n\n```\n \n```\n```rescript\ntype JsxEvent.Clipboard.t = synthetic\n```\nGo to: [Type definition](JsxEvent.res#L78,3)\n\n\n---\n\n```\n \n```\n```rescript\ntype JsxEvent.Composition.t = synthetic\n```\nGo to: [Type definition](JsxEvent.res#L88,3)\n\n\n---\n\n```\n \n```\n```rescript\ntype JsxEvent.Keyboard.t = synthetic\n```\nGo to: [Type definition](JsxEvent.res#L97,3)\n\n\n---\n\n```\n \n```\n```rescript\ntype JsxEvent.Focus.t = synthetic\n```\nGo to: [Type definition](JsxEvent.res#L119,3)\n\n\n---\n\n```\n \n```\n```rescript\ntype JsxEvent.Form.t = synthetic\n```\nGo to: [Type definition](JsxEvent.res#L129,3)\n\n\n---\n\n```\n \n```\n```rescript\ntype JsxEvent.Mouse.t = synthetic\n```\nGo to: [Type definition](JsxEvent.res#L136,3)\n\n\n---\n\n```\n \n```\n```rescript\ntype JsxEvent.Selection.t = synthetic\n```\nGo to: [Type definition](JsxEvent.res#L213,3)\n\n\n---\n\n```\n \n```\n```rescript\ntype JsxEvent.Touch.t = synthetic\n```\nGo to: [Type definition](JsxEvent.res#L220,3)\n\n\n---\n\n```\n \n```\n```rescript\ntype JsxEvent.Pointer.t = synthetic\n```\nGo to: [Type definition](JsxEvent.res#L165,3)\n\n\n---\n\n```\n \n```\n```rescript\ntype JsxEvent.UI.t = synthetic\n```\nGo to: [Type definition](JsxEvent.res#L243,3)\n\n\n---\n\n```\n \n```\n```rescript\ntype JsxEvent.Wheel.t = synthetic\n```\nGo to: [Type definition](JsxEvent.res#L254,3)\n\n\n---\n\n```\n \n```\n```rescript\ntype JsxEvent.Media.t = synthetic\n```\nGo to: [Type definition](JsxEvent.res#L266,3)\n\n\n---\n\n```\n \n```\n```rescript\ntype JsxEvent.Image.t = synthetic\n```\nGo to: [Type definition](JsxEvent.res#L273,3)\n\n\n---\n\n```\n \n```\n```rescript\ntype JsxEvent.Animation.t = synthetic\n```\nGo to: [Type definition](JsxEvent.res#L280,3)\n\n\n---\n\n```\n \n```\n```rescript\ntype JsxEvent.Transition.t = synthetic\n```\nGo to: [Type definition](JsxEvent.res#L291,3)\n" + "value": "```rescript\nJsxDOM.domProps\n```\n\n---\n\n```\n \n```\n```rescript\ntype JsxDOM.domProps = {\n key?: string,\n children?: Jsx.element,\n ref?: domRef,\n allow?: string,\n @as(\"aria-current\") ariaCurrent?: [\n | #date\n | #\"false\"\n | #location\n | #page\n | #step\n | #time\n | #\"true\"\n ],\n @as(\"aria-details\") ariaDetails?: string,\n @as(\"aria-disabled\") ariaDisabled?: bool,\n @as(\"aria-hidden\") ariaHidden?: bool,\n @as(\"aria-invalid\") ariaInvalid?: [\n | #\"false\"\n | #grammar\n | #spelling\n | #\"true\"\n ],\n @as(\"aria-keyshortcuts\") ariaKeyshortcuts?: string,\n @as(\"aria-label\") ariaLabel?: string,\n @as(\"aria-roledescription\") ariaRoledescription?: string,\n @as(\"aria-autocomplete\") ariaAutocomplete?: [\n | #both\n | #inline\n | #list\n | #none\n ],\n @as(\"aria-checked\") ariaChecked?: [\n | #\"false\"\n | #mixed\n | #\"true\"\n ],\n @as(\"aria-expanded\") ariaExpanded?: bool,\n @as(\"aria-haspopup\") ariaHaspopup?: [\n | #dialog\n | #\"false\"\n | #grid\n | #listbox\n | #menu\n | #tree\n | #\"true\"\n ],\n @as(\"aria-level\") ariaLevel?: int,\n @as(\"aria-modal\") ariaModal?: bool,\n @as(\"aria-multiline\") ariaMultiline?: bool,\n @as(\"aria-multiselectable\") ariaMultiselectable?: bool,\n @as(\"aria-orientation\") ariaOrientation?: [\n | #horizontal\n | #undefined\n | #vertical\n ],\n @as(\"aria-placeholder\") ariaPlaceholder?: string,\n @as(\"aria-pressed\") ariaPressed?: [\n | #\"false\"\n | #mixed\n | #\"true\"\n ],\n @as(\"aria-readonly\") ariaReadonly?: bool,\n @as(\"aria-required\") ariaRequired?: bool,\n @as(\"aria-selected\") ariaSelected?: bool,\n @as(\"aria-sort\") ariaSort?: string,\n @as(\"aria-valuemax\") ariaValuemax?: float,\n @as(\"aria-valuemin\") ariaValuemin?: float,\n @as(\"aria-valuenow\") ariaValuenow?: float,\n @as(\"aria-valuetext\") ariaValuetext?: string,\n @as(\"aria-atomic\") ariaAtomic?: bool,\n @as(\"aria-busy\") ariaBusy?: bool,\n @as(\"aria-live\") ariaLive?: [\n | #assertive\n | #off\n | #polite\n | #rude\n ],\n @as(\"aria-relevant\") ariaRelevant?: string,\n @as(\"aria-dropeffect\") ariaDropeffect?: [\n | #copy\n | #execute\n | #link\n | #move\n | #none\n | #popup\n ],\n @as(\"aria-grabbed\") ariaGrabbed?: bool,\n @as(\"aria-activedescendant\") ariaActivedescendant?: string,\n @as(\"aria-colcount\") ariaColcount?: int,\n @as(\"aria-colindex\") ariaColindex?: int,\n @as(\"aria-colspan\") ariaColspan?: int,\n @as(\"aria-controls\") ariaControls?: string,\n @as(\"aria-describedby\") ariaDescribedby?: string,\n @as(\"aria-errormessage\") ariaErrormessage?: string,\n @as(\"aria-flowto\") ariaFlowto?: string,\n @as(\"aria-labelledby\") ariaLabelledby?: string,\n @as(\"aria-owns\") ariaOwns?: string,\n @as(\"aria-posinset\") ariaPosinset?: int,\n @as(\"aria-rowcount\") ariaRowcount?: int,\n @as(\"aria-rowindex\") ariaRowindex?: int,\n @as(\"aria-rowspan\") ariaRowspan?: int,\n @as(\"aria-setsize\") ariaSetsize?: int,\n defaultChecked?: bool,\n defaultValue?: string,\n accessKey?: string,\n capture?: [#environment | #user],\n className?: string,\n contentEditable?: bool,\n contextMenu?: string,\n @as(\"data-testid\") dataTestId?: string,\n dir?: string,\n draggable?: bool,\n hidden?: bool,\n id?: string,\n inert?: bool,\n lang?: string,\n popover?: popover,\n popoverTarget?: string,\n popoverTargetAction?: popoverTargetAction,\n role?: string,\n style?: style,\n spellCheck?: bool,\n tabIndex?: int,\n title?: string,\n itemID?: string,\n itemProp?: string,\n itemRef?: string,\n itemScope?: bool,\n itemType?: string,\n accept?: string,\n acceptCharset?: string,\n action?: string,\n allowFullScreen?: bool,\n alt?: string,\n @as(\"as\") as_?: string,\n async?: bool,\n autoComplete?: string,\n autoCapitalize?: string,\n autoFocus?: bool,\n autoPlay?: bool,\n challenge?: string,\n charSet?: string,\n checked?: bool,\n cite?: string,\n crossOrigin?: string,\n cols?: int,\n colSpan?: int,\n content?: string,\n controls?: bool,\n coords?: string,\n data?: string,\n dateTime?: string,\n default?: bool,\n defer?: bool,\n disabled?: bool,\n download?: string,\n encType?: string,\n form?: string,\n formAction?: string,\n formTarget?: string,\n formMethod?: string,\n frameBorder?: int,\n headers?: string,\n height?: string,\n high?: int,\n href?: string,\n hrefLang?: string,\n htmlFor?: string,\n httpEquiv?: string,\n icon?: string,\n inputMode?: string,\n integrity?: string,\n keyType?: string,\n kind?: string,\n label?: string,\n list?: string,\n loading?: [#eager | #lazy],\n loop?: bool,\n low?: int,\n manifest?: string,\n max?: string,\n maxLength?: int,\n media?: string,\n mediaGroup?: string,\n method?: string,\n min?: string,\n minLength?: int,\n multiple?: bool,\n muted?: bool,\n name?: string,\n nonce?: string,\n noValidate?: bool,\n @as(\"open\") open_?: bool,\n optimum?: int,\n pattern?: string,\n placeholder?: string,\n playsInline?: bool,\n poster?: string,\n preload?: string,\n radioGroup?: string,\n readOnly?: bool,\n rel?: string,\n required?: bool,\n reversed?: bool,\n rows?: int,\n rowSpan?: int,\n sandbox?: string,\n scope?: string,\n scoped?: bool,\n scrolling?: string,\n selected?: bool,\n shape?: string,\n size?: int,\n sizes?: string,\n span?: int,\n src?: string,\n srcDoc?: string,\n srcLang?: string,\n srcSet?: string,\n start?: int,\n step?: float,\n summary?: string,\n target?: string,\n @as(\"type\") type_?: string,\n useMap?: string,\n value?: string,\n width?: string,\n wrap?: string,\n onCopy?: JsxEvent.Clipboard.t => unit,\n onCut?: JsxEvent.Clipboard.t => unit,\n onPaste?: JsxEvent.Clipboard.t => unit,\n onCompositionEnd?: JsxEvent.Composition.t => unit,\n onCompositionStart?: JsxEvent.Composition.t => unit,\n onCompositionUpdate?: JsxEvent.Composition.t => unit,\n onKeyDown?: JsxEvent.Keyboard.t => unit,\n onKeyPress?: JsxEvent.Keyboard.t => unit,\n onKeyUp?: JsxEvent.Keyboard.t => unit,\n onFocus?: JsxEvent.Focus.t => unit,\n onBlur?: JsxEvent.Focus.t => unit,\n onBeforeInput?: JsxEvent.Form.t => unit,\n onChange?: JsxEvent.Form.t => unit,\n onInput?: JsxEvent.Form.t => unit,\n onReset?: JsxEvent.Form.t => unit,\n onSubmit?: JsxEvent.Form.t => unit,\n onInvalid?: JsxEvent.Form.t => unit,\n onClick?: JsxEvent.Mouse.t => unit,\n onContextMenu?: JsxEvent.Mouse.t => unit,\n onDoubleClick?: JsxEvent.Mouse.t => unit,\n onDrag?: JsxEvent.Mouse.t => unit,\n onDragEnd?: JsxEvent.Mouse.t => unit,\n onDragEnter?: JsxEvent.Mouse.t => unit,\n onDragExit?: JsxEvent.Mouse.t => unit,\n onDragLeave?: JsxEvent.Mouse.t => unit,\n onDragOver?: JsxEvent.Mouse.t => unit,\n onDragStart?: JsxEvent.Mouse.t => unit,\n onDrop?: JsxEvent.Mouse.t => unit,\n onMouseDown?: JsxEvent.Mouse.t => unit,\n onMouseEnter?: JsxEvent.Mouse.t => unit,\n onMouseLeave?: JsxEvent.Mouse.t => unit,\n onMouseMove?: JsxEvent.Mouse.t => unit,\n onMouseOut?: JsxEvent.Mouse.t => unit,\n onMouseOver?: JsxEvent.Mouse.t => unit,\n onMouseUp?: JsxEvent.Mouse.t => unit,\n onSelect?: JsxEvent.Selection.t => unit,\n onTouchCancel?: JsxEvent.Touch.t => unit,\n onTouchEnd?: JsxEvent.Touch.t => unit,\n onTouchMove?: JsxEvent.Touch.t => unit,\n onTouchStart?: JsxEvent.Touch.t => unit,\n onPointerOver?: JsxEvent.Pointer.t => unit,\n onPointerEnter?: JsxEvent.Pointer.t => unit,\n onPointerDown?: JsxEvent.Pointer.t => unit,\n onPointerMove?: JsxEvent.Pointer.t => unit,\n onPointerUp?: JsxEvent.Pointer.t => unit,\n onPointerCancel?: JsxEvent.Pointer.t => unit,\n onPointerOut?: JsxEvent.Pointer.t => unit,\n onPointerLeave?: JsxEvent.Pointer.t => unit,\n onGotPointerCapture?: JsxEvent.Pointer.t => unit,\n onLostPointerCapture?: JsxEvent.Pointer.t => unit,\n onScroll?: JsxEvent.UI.t => unit,\n onWheel?: JsxEvent.Wheel.t => unit,\n onAbort?: JsxEvent.Media.t => unit,\n onCanPlay?: JsxEvent.Media.t => unit,\n onCanPlayThrough?: JsxEvent.Media.t => unit,\n onDurationChange?: JsxEvent.Media.t => unit,\n onEmptied?: JsxEvent.Media.t => unit,\n onEncrypted?: JsxEvent.Media.t => unit,\n onEnded?: JsxEvent.Media.t => unit,\n onError?: JsxEvent.Media.t => unit,\n onLoadedData?: JsxEvent.Media.t => unit,\n onLoadedMetadata?: JsxEvent.Media.t => unit,\n onLoadStart?: JsxEvent.Media.t => unit,\n onPause?: JsxEvent.Media.t => unit,\n onPlay?: JsxEvent.Media.t => unit,\n onPlaying?: JsxEvent.Media.t => unit,\n onProgress?: JsxEvent.Media.t => unit,\n onRateChange?: JsxEvent.Media.t => unit,\n onSeeked?: JsxEvent.Media.t => unit,\n onSeeking?: JsxEvent.Media.t => unit,\n onStalled?: JsxEvent.Media.t => unit,\n onSuspend?: JsxEvent.Media.t => unit,\n onTimeUpdate?: JsxEvent.Media.t => unit,\n onVolumeChange?: JsxEvent.Media.t => unit,\n onWaiting?: JsxEvent.Media.t => unit,\n onLoad?: JsxEvent.Image.t => unit,\n onAnimationStart?: JsxEvent.Animation.t => unit,\n onAnimationEnd?: JsxEvent.Animation.t => unit,\n onAnimationIteration?: JsxEvent.Animation.t => unit,\n onTransitionEnd?: JsxEvent.Transition.t => unit,\n accentHeight?: string,\n accumulate?: string,\n additive?: string,\n alignmentBaseline?: string,\n allowReorder?: string,\n alphabetic?: string,\n amplitude?: string,\n arabicForm?: string,\n ascent?: string,\n attributeName?: string,\n attributeType?: string,\n autoReverse?: string,\n azimuth?: string,\n baseFrequency?: string,\n baseProfile?: string,\n baselineShift?: string,\n bbox?: string,\n begin?: string,\n bias?: string,\n by?: string,\n calcMode?: string,\n capHeight?: string,\n clip?: string,\n clipPath?: string,\n clipPathUnits?: string,\n clipRule?: string,\n colorInterpolation?: string,\n colorInterpolationFilters?: string,\n colorProfile?: string,\n colorRendering?: string,\n contentScriptType?: string,\n contentStyleType?: string,\n cursor?: string,\n cx?: string,\n cy?: string,\n d?: string,\n decelerate?: string,\n descent?: string,\n diffuseConstant?: string,\n direction?: string,\n display?: string,\n divisor?: string,\n dominantBaseline?: string,\n dur?: string,\n dx?: string,\n dy?: string,\n edgeMode?: string,\n elevation?: string,\n enableBackground?: string,\n end?: string,\n exponent?: string,\n externalResourcesRequired?: string,\n fill?: string,\n fillOpacity?: string,\n fillRule?: string,\n filter?: string,\n filterRes?: string,\n filterUnits?: string,\n floodColor?: string,\n floodOpacity?: string,\n focusable?: string,\n fontFamily?: string,\n fontSize?: string,\n fontSizeAdjust?: string,\n fontStretch?: string,\n fontStyle?: string,\n fontVariant?: string,\n fontWeight?: string,\n fomat?: string,\n from?: string,\n fx?: string,\n fy?: string,\n g1?: string,\n g2?: string,\n glyphName?: string,\n glyphOrientationHorizontal?: string,\n glyphOrientationVertical?: string,\n glyphRef?: string,\n gradientTransform?: string,\n gradientUnits?: string,\n hanging?: string,\n horizAdvX?: string,\n horizOriginX?: string,\n ideographic?: string,\n imageRendering?: string,\n @as(\"in\") in_?: string,\n in2?: string,\n intercept?: string,\n k?: string,\n k1?: string,\n k2?: string,\n k3?: string,\n k4?: string,\n kernelMatrix?: string,\n kernelUnitLength?: string,\n kerning?: string,\n keyPoints?: string,\n keySplines?: string,\n keyTimes?: string,\n lengthAdjust?: string,\n letterSpacing?: string,\n lightingColor?: string,\n limitingConeAngle?: string,\n local?: string,\n markerEnd?: string,\n markerHeight?: string,\n markerMid?: string,\n markerStart?: string,\n markerUnits?: string,\n markerWidth?: string,\n mask?: string,\n maskContentUnits?: string,\n maskUnits?: string,\n mathematical?: string,\n mode?: string,\n numOctaves?: string,\n offset?: string,\n opacity?: string,\n operator?: string,\n order?: string,\n orient?: string,\n orientation?: string,\n origin?: string,\n overflow?: string,\n overflowX?: string,\n overflowY?: string,\n overlinePosition?: string,\n overlineThickness?: string,\n paintOrder?: string,\n panose1?: string,\n pathLength?: string,\n patternContentUnits?: string,\n patternTransform?: string,\n patternUnits?: string,\n pointerEvents?: string,\n points?: string,\n pointsAtX?: string,\n pointsAtY?: string,\n pointsAtZ?: string,\n preserveAlpha?: string,\n preserveAspectRatio?: string,\n primitiveUnits?: string,\n r?: string,\n radius?: string,\n referrerPolicy?: string,\n refX?: string,\n refY?: string,\n renderingIntent?: string,\n repeatCount?: string,\n repeatDur?: string,\n requiredExtensions?: string,\n requiredFeatures?: string,\n restart?: string,\n result?: string,\n rotate?: string,\n rx?: string,\n ry?: string,\n scale?: string,\n seed?: string,\n shapeRendering?: string,\n slope?: string,\n slot?: string,\n spacing?: string,\n specularConstant?: string,\n specularExponent?: string,\n speed?: string,\n spreadMethod?: string,\n startOffset?: string,\n stdDeviation?: string,\n stemh?: string,\n stemv?: string,\n stitchTiles?: string,\n stopColor?: string,\n stopOpacity?: string,\n strikethroughPosition?: string,\n strikethroughThickness?: string,\n string?: string,\n stroke?: string,\n strokeDasharray?: string,\n strokeDashoffset?: string,\n strokeLinecap?: string,\n strokeLinejoin?: string,\n strokeMiterlimit?: string,\n strokeOpacity?: string,\n strokeWidth?: string,\n surfaceScale?: string,\n systemLanguage?: string,\n tableValues?: string,\n targetX?: string,\n targetY?: string,\n textAnchor?: string,\n textDecoration?: string,\n textLength?: string,\n textRendering?: string,\n to?: string,\n transform?: string,\n u1?: string,\n u2?: string,\n underlinePosition?: string,\n underlineThickness?: string,\n unicode?: string,\n unicodeBidi?: string,\n unicodeRange?: string,\n unitsPerEm?: string,\n vAlphabetic?: string,\n vHanging?: string,\n vIdeographic?: string,\n vMathematical?: string,\n values?: string,\n vectorEffect?: string,\n version?: string,\n vertAdvX?: string,\n vertAdvY?: string,\n vertOriginX?: string,\n vertOriginY?: string,\n viewBox?: string,\n viewTarget?: string,\n visibility?: string,\n widths?: string,\n wordSpacing?: string,\n writingMode?: string,\n x?: string,\n x1?: string,\n x2?: string,\n xChannelSelector?: string,\n xHeight?: string,\n xlinkActuate?: string,\n xlinkArcrole?: string,\n xlinkHref?: string,\n xlinkRole?: string,\n xlinkShow?: string,\n xlinkTitle?: string,\n xlinkType?: string,\n xmlns?: string,\n xmlnsXlink?: string,\n xmlBase?: string,\n xmlLang?: string,\n xmlSpace?: string,\n y?: string,\n y1?: string,\n y2?: string,\n yChannelSelector?: string,\n z?: string,\n zoomAndPan?: string,\n about?: string,\n datatype?: string,\n inlist?: string,\n prefix?: string,\n property?: string,\n resource?: string,\n typeof?: string,\n vocab?: string,\n dangerouslySetInnerHTML?: {\"__html\": string},\n suppressContentEditableWarning?: bool,\n}\n```\nGo to: [Type definition](JsxDOM.res#L21,1)\n\n\n---\n\n```\n \n```\n```rescript\ntype Jsx.element\n```\nGo to: [Type definition](Jsx.res#L8,1)\n\n\n---\n\n```\n \n```\n```rescript\ntype domRef\n```\nGo to: [Type definition](JsxDOM.res#L8,1)\n\n\n---\n\n```\n \n```\n```rescript\ntype popover =\n | @as(\"auto\") Auto\n | @as(\"manual\") Manual\n | @as(\"hint\") Hint\n```\nGo to: [Type definition](JsxDOM.res#L12,1)\n\n\n---\n\n```\n \n```\n```rescript\ntype popoverTargetAction =\n | @as(\"toggle\") Toggle\n | @as(\"show\") Show\n | @as(\"hide\") Hide\n```\nGo to: [Type definition](JsxDOM.res#L16,1)\n\n\n---\n\n```\n \n```\n```rescript\ntype style = JsxDOMStyle.t\n```\nGo to: [Type definition](JsxDOM.res#L7,1)\n\n\n---\n\n```\n \n```\n```rescript\ntype JsxEvent.Clipboard.t = synthetic\n```\nGo to: [Type definition](JsxEvent.res#L78,3)\n\n\n---\n\n```\n \n```\n```rescript\ntype JsxEvent.Composition.t = synthetic\n```\nGo to: [Type definition](JsxEvent.res#L88,3)\n\n\n---\n\n```\n \n```\n```rescript\ntype JsxEvent.Keyboard.t = synthetic\n```\nGo to: [Type definition](JsxEvent.res#L97,3)\n\n\n---\n\n```\n \n```\n```rescript\ntype JsxEvent.Focus.t = synthetic\n```\nGo to: [Type definition](JsxEvent.res#L119,3)\n\n\n---\n\n```\n \n```\n```rescript\ntype JsxEvent.Form.t = synthetic\n```\nGo to: [Type definition](JsxEvent.res#L129,3)\n\n\n---\n\n```\n \n```\n```rescript\ntype JsxEvent.Mouse.t = synthetic\n```\nGo to: [Type definition](JsxEvent.res#L136,3)\n\n\n---\n\n```\n \n```\n```rescript\ntype JsxEvent.Selection.t = synthetic\n```\nGo to: [Type definition](JsxEvent.res#L213,3)\n\n\n---\n\n```\n \n```\n```rescript\ntype JsxEvent.Touch.t = synthetic\n```\nGo to: [Type definition](JsxEvent.res#L220,3)\n\n\n---\n\n```\n \n```\n```rescript\ntype JsxEvent.Pointer.t = synthetic\n```\nGo to: [Type definition](JsxEvent.res#L165,3)\n\n\n---\n\n```\n \n```\n```rescript\ntype JsxEvent.UI.t = synthetic\n```\nGo to: [Type definition](JsxEvent.res#L243,3)\n\n\n---\n\n```\n \n```\n```rescript\ntype JsxEvent.Wheel.t = synthetic\n```\nGo to: [Type definition](JsxEvent.res#L254,3)\n\n\n---\n\n```\n \n```\n```rescript\ntype JsxEvent.Media.t = synthetic\n```\nGo to: [Type definition](JsxEvent.res#L266,3)\n\n\n---\n\n```\n \n```\n```rescript\ntype JsxEvent.Image.t = synthetic\n```\nGo to: [Type definition](JsxEvent.res#L273,3)\n\n\n---\n\n```\n \n```\n```rescript\ntype JsxEvent.Animation.t = synthetic\n```\nGo to: [Type definition](JsxEvent.res#L280,3)\n\n\n---\n\n```\n \n```\n```rescript\ntype JsxEvent.Transition.t = synthetic\n```\nGo to: [Type definition](JsxEvent.res#L291,3)\n" } } diff --git a/tests/analysis_tests/tests/src/expected/CreateInterfaceFunctor.res.txt b/tests/analysis_tests/tests/src/expected/CreateInterfaceFunctor.res.txt index 1e6f4877f5c..3abb4e8fae5 100644 --- a/tests/analysis_tests/tests/src/expected/CreateInterfaceFunctor.res.txt +++ b/tests/analysis_tests/tests/src/expected/CreateInterfaceFunctor.res.txt @@ -23,4 +23,14 @@ module type S = { module N: { type t = {@as("wire") field: int} } +module WithWire: ( + X: { + }, +) => +{ + type t = {@as("wire") field: int} +} +module Applied: { + type t = {@as("wire") field: int} +}