From be1b82ad6c54d915b1ef91701d0f0f28053016d7 Mon Sep 17 00:00:00 2001 From: Woonki Moon Date: Wed, 14 Dec 2022 00:19:06 +0900 Subject: [PATCH 1/7] add test --- .../ppx/react/expected/mangleKeyword.res.txt | 68 +++++++++++++++++++ res_syntax/tests/ppx/react/mangleKeyword.res | 43 ++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 res_syntax/tests/ppx/react/expected/mangleKeyword.res.txt create mode 100644 res_syntax/tests/ppx/react/mangleKeyword.res diff --git a/res_syntax/tests/ppx/react/expected/mangleKeyword.res.txt b/res_syntax/tests/ppx/react/expected/mangleKeyword.res.txt new file mode 100644 index 0000000000..0ebb76e886 --- /dev/null +++ b/res_syntax/tests/ppx/react/expected/mangleKeyword.res.txt @@ -0,0 +1,68 @@ +@@jsxConfig({version: 3}) + +module C0 = { + @obj external makeProps: (~_open: 'T_open, ~key: string=?, unit) => {"_open": 'T_open} = "" + + @react.component let make = @warning("-16") (~_open) => React.string(_open) + let make = { + let \"MangleKeyword$C0" = (\"Props": {"_open": 'T_open}) => make(~_open=\"Props"["_open"]) + \"MangleKeyword$C0" + } +} +module C1 = { + @obj external makeProps: (~_open: string, ~key: string=?, unit) => {"_open": string} = "" + external make: React.componentLike<{"_open": string}, React.element> = "default" +} + +let c0 = React.createElement(C0.make, C0.makeProps(~_open="x", ())) +let c1 = React.createElement(C1.make, C1.makeProps(~_open="x", ())) + +@@jsxConfig({version: 4, mode: "classic"}) + +module C0 = { + type props<'T_open> = { + _open: 'T_open, + } + + @react.component let make = ({@as("open") _open, _}: props<'T_open>) => React.string(_open) + let make = { + let \"MangleKeyword$C0" = (props: props<_>) => make(props) + + \"MangleKeyword$C0" + } +} +module C1 = { + type props<'T_open> = { + _open: 'T_open, + } + + external make: @as("open") React.componentLike, React.element> = "default" +} + +let c0 = React.createElement(C0.make, {_open: "x"}) +let c1 = React.createElement(C1.make, {_open: "x"}) + +@@jsxConfig({version: 4, mode: "automatic"}) + +module C0 = { + type props<'T_open> = { + _open: 'T_open, + } + + @react.component let make = ({@as("open") _open, _}: props<'T_open>) => React.string(_open) + let make = { + let \"MangleKeyword$C0" = (props: props<_>) => make(props) + + \"MangleKeyword$C0" + } +} +module C1 = { + type props<'T_open> = { + _open: 'T_open, + } + + external make: @as("open") React.componentLike, React.element> = "default" +} + +let c0 = React.jsx(C0.make, {_open: "x"}) +let c1 = React.jsx(C1.make, {_open: "x"}) diff --git a/res_syntax/tests/ppx/react/mangleKeyword.res b/res_syntax/tests/ppx/react/mangleKeyword.res new file mode 100644 index 0000000000..2da46fa5da --- /dev/null +++ b/res_syntax/tests/ppx/react/mangleKeyword.res @@ -0,0 +1,43 @@ +@@jsxConfig({version: 3}) + +module C0 = { + @react.component + let make = (~_open) => React.string(_open) +} +module C1 = { + @react.component + external make: (~_open: string) => React.element = "default" +} + +let c0 = +let c1 = + +@@jsxConfig({version: 4, mode: "classic"}) + +module C0 = { + @react.component + let make = + (@as("open") ~_open) => React.string(_open) +} +module C1 = { + @react.component + external make: (@as("open") ~_open: string) => React.element = "default" +} + +let c0 = +let c1 = + +@@jsxConfig({version: 4, mode: "automatic"}) + +module C0 = { + @react.component + let make = + (@as("open") ~_open) => React.string(_open) +} +module C1 = { + @react.component + external make: (@as("open") ~_open: string) => React.element = "default" +} + +let c0 = +let c1 = From 6e73efe58614caed259e177ea69a4838f75cadf1 Mon Sep 17 00:00:00 2001 From: Woonki Moon Date: Wed, 14 Dec 2022 01:22:07 +0900 Subject: [PATCH 2/7] make record type for props with attrs --- res_syntax/src/reactjs_jsx_v4.ml | 49 ++++++++++++------- .../ppx/react/expected/mangleKeyword.res.txt | 40 +++++++++------ res_syntax/tests/ppx/react/mangleKeyword.res | 18 ++++--- 3 files changed, 64 insertions(+), 43 deletions(-) diff --git a/res_syntax/src/reactjs_jsx_v4.ml b/res_syntax/src/reactjs_jsx_v4.ml index ae586bcb61..183e61df1a 100644 --- a/res_syntax/src/reactjs_jsx_v4.ml +++ b/res_syntax/src/reactjs_jsx_v4.ml @@ -289,14 +289,15 @@ let makePropsTypeParams ?(stripExplicitOption = false) let makeLabelDecls ~loc namedTypeList = namedTypeList - |> List.map (fun (isOptional, label, _, interiorType) -> + |> List.map (fun (isOptional, label, attrs, interiorType) -> if label = "key" then - Type.field ~loc ~attrs:optionalAttrs {txt = label; loc} interiorType + Type.field ~loc ~attrs:(optionalAttrs @ attrs) {txt = label; loc} + interiorType else if isOptional then - Type.field ~loc ~attrs:optionalAttrs {txt = label; loc} + Type.field ~loc ~attrs:(optionalAttrs @ attrs) {txt = label; loc} (Typ.var @@ safeTypeFromValue @@ Labelled label) else - Type.field ~loc {txt = label; loc} + Type.field ~loc ~attrs {txt = label; loc} (Typ.var @@ safeTypeFromValue @@ Labelled label)) let makeTypeDecls propsName loc namedTypeList = @@ -681,7 +682,9 @@ let newtypeToVar newtype type_ = mapper.typ mapper type_ let argToType ~newtypes ~(typeConstraints : core_type option) types - (name, default, _noLabelName, _alias, loc, type_) = + ((name, default, {ppat_attributes = attrs}, _alias, loc, type_) : + arg_label * expression option * pattern * label * 'loc * core_type option) + = let rec getType name coreType = match coreType with | {ptyp_desc = Ptyp_arrow (arg, c1, c2)} -> @@ -699,17 +702,18 @@ let argToType ~newtypes ~(typeConstraints : core_type option) types in match (type_, name, default) with | Some type_, name, _ when isOptional name -> - (true, getLabel name, [], {type_ with ptyp_attributes = optionalAttrs}) + (true, getLabel name, attrs, {type_ with ptyp_attributes = optionalAttrs}) :: types - | Some type_, name, _ -> (false, getLabel name, [], type_) :: types + | Some type_, name, _ -> (false, getLabel name, attrs, type_) :: types | None, name, _ when isOptional name -> ( true, getLabel name, - [], + attrs, Typ.var ~loc ~attrs:optionalAttrs (safeTypeFromValue name) ) :: types | None, name, _ when isLabelled name -> - (false, getLabel name, [], Typ.var ~loc (safeTypeFromValue name)) :: types + (false, getLabel name, attrs, Typ.var ~loc (safeTypeFromValue name)) + :: types | _ -> types let argWithDefaultValue (name, default, _, _, _, _) = @@ -717,10 +721,10 @@ let argWithDefaultValue (name, default, _, _, _, _) = | Some default when isOptional name -> Some (getLabel name, default) | _ -> None -let argToConcreteType types (name, _loc, type_) = +let argToConcreteType types (name, attrs, _loc, type_) = match name with - | name when isLabelled name -> (false, getLabel name, [], type_) :: types - | name when isOptional name -> (true, getLabel name, [], type_) :: types + | name when isLabelled name -> (false, getLabel name, attrs, type_) :: types + | name when isOptional name -> (true, getLabel name, attrs, type_) :: types | _ -> types let check_string_int_attribute_iter = @@ -763,15 +767,19 @@ let transformStructureItem ~config mapper item = |> Option.map React_jsx_common.typVarsOfCoreType |> Option.value ~default:[] in - let rec getPropTypes types ({ptyp_loc; ptyp_desc} as fullType) = + let rec getPropTypes types + ({ptyp_loc; ptyp_desc; ptyp_attributes} as fullType) = match ptyp_desc with | Ptyp_arrow (name, type_, ({ptyp_desc = Ptyp_arrow _} as rest)) when isLabelled name || isOptional name -> - getPropTypes ((name, ptyp_loc, type_) :: types) rest + getPropTypes + ((name, ptyp_attributes, ptyp_loc, type_) :: types) + rest | Ptyp_arrow (Nolabel, _type, rest) -> getPropTypes types rest | Ptyp_arrow (name, type_, returnValue) when isLabelled name || isOptional name -> - (returnValue, (name, returnValue.ptyp_loc, type_) :: types) + ( returnValue, + (name, ptyp_attributes, returnValue.ptyp_loc, type_) :: types ) | _ -> (fullType, types) in let innerType, propTypes = getPropTypes [] pval_type in @@ -1264,9 +1272,12 @@ let transformSignatureItem ~config _mapper item = in let rec getPropTypes types ({ptyp_loc; ptyp_desc} as fullType) = match ptyp_desc with - | Ptyp_arrow (name, type_, ({ptyp_desc = Ptyp_arrow _} as rest)) + | Ptyp_arrow + ( name, + ({ptyp_attributes = attrs} as type_), + ({ptyp_desc = Ptyp_arrow _} as rest) ) when isOptional name || isLabelled name -> - getPropTypes ((name, ptyp_loc, type_) :: types) rest + getPropTypes ((name, attrs, ptyp_loc, type_) :: types) rest | Ptyp_arrow (Nolabel, {ptyp_desc = Ptyp_constr ({txt = Lident "unit"}, _)}, rest) -> @@ -1274,9 +1285,9 @@ let transformSignatureItem ~config _mapper item = | Ptyp_arrow (Nolabel, _type, rest) -> hasForwardRef := true; getPropTypes types rest - | Ptyp_arrow (name, type_, returnValue) + | Ptyp_arrow (name, ({ptyp_attributes = attrs} as type_), returnValue) when isOptional name || isLabelled name -> - (returnValue, (name, returnValue.ptyp_loc, type_) :: types) + (returnValue, (name, attrs, returnValue.ptyp_loc, type_) :: types) | _ -> (fullType, types) in let innerType, propTypes = getPropTypes [] pval_type in diff --git a/res_syntax/tests/ppx/react/expected/mangleKeyword.res.txt b/res_syntax/tests/ppx/react/expected/mangleKeyword.res.txt index 0ebb76e886..ff8804e380 100644 --- a/res_syntax/tests/ppx/react/expected/mangleKeyword.res.txt +++ b/res_syntax/tests/ppx/react/expected/mangleKeyword.res.txt @@ -20,11 +20,14 @@ let c1 = React.createElement(C1.make, C1.makeProps(~_open="x", ())) @@jsxConfig({version: 4, mode: "classic"}) module C0 = { - type props<'T_open> = { - _open: 'T_open, + type props<'T_open, 'T_type> = { + @as("open") _open: 'T_open, + @as("type") _type: 'T_type, } - @react.component let make = ({@as("open") _open, _}: props<'T_open>) => React.string(_open) + @react.component + let make = ({@as("open") _open, @as("type") _type, _}: props<'T_open, string>) => + React.string(_open) let make = { let \"MangleKeyword$C0" = (props: props<_>) => make(props) @@ -32,24 +35,28 @@ module C0 = { } } module C1 = { - type props<'T_open> = { - _open: 'T_open, + type props<'T_open, 'T_type> = { + @as("open") _open: 'T_open, + @as("type") _type: 'T_type, } - external make: @as("open") React.componentLike, React.element> = "default" + external make: @as("open") React.componentLike, React.element> = "default" } -let c0 = React.createElement(C0.make, {_open: "x"}) -let c1 = React.createElement(C1.make, {_open: "x"}) +let c0 = React.createElement(C0.make, {_open: "x", _type: "t"}) +let c1 = React.createElement(C1.make, {_open: "x", _type: "t"}) @@jsxConfig({version: 4, mode: "automatic"}) module C0 = { - type props<'T_open> = { - _open: 'T_open, + type props<'T_open, 'T_type> = { + @as("open") _open: 'T_open, + @as("type") _type: 'T_type, } - @react.component let make = ({@as("open") _open, _}: props<'T_open>) => React.string(_open) + @react.component + let make = ({@as("open") _open, @as("type") _type, _}: props<'T_open, string>) => + React.string(_open) let make = { let \"MangleKeyword$C0" = (props: props<_>) => make(props) @@ -57,12 +64,13 @@ module C0 = { } } module C1 = { - type props<'T_open> = { - _open: 'T_open, + type props<'T_open, 'T_type> = { + @as("open") _open: 'T_open, + @as("type") _type: 'T_type, } - external make: @as("open") React.componentLike, React.element> = "default" + external make: @as("open") React.componentLike, React.element> = "default" } -let c0 = React.jsx(C0.make, {_open: "x"}) -let c1 = React.jsx(C1.make, {_open: "x"}) +let c0 = React.jsx(C0.make, {_open: "x", _type: "t"}) +let c1 = React.jsx(C1.make, {_open: "x", _type: "t"}) diff --git a/res_syntax/tests/ppx/react/mangleKeyword.res b/res_syntax/tests/ppx/react/mangleKeyword.res index 2da46fa5da..c40da3b4f1 100644 --- a/res_syntax/tests/ppx/react/mangleKeyword.res +++ b/res_syntax/tests/ppx/react/mangleKeyword.res @@ -17,27 +17,29 @@ let c1 = module C0 = { @react.component let make = - (@as("open") ~_open) => React.string(_open) + (@as("open") ~_open, @as("type") ~_type: string) => React.string(_open) } module C1 = { @react.component - external make: (@as("open") ~_open: string) => React.element = "default" + external make: (@as("open") ~_open: string, @as("type") ~_type: string) => React.element = + "default" } -let c0 = -let c1 = +let c0 = +let c1 = @@jsxConfig({version: 4, mode: "automatic"}) module C0 = { @react.component let make = - (@as("open") ~_open) => React.string(_open) + (@as("open") ~_open, @as("type") ~_type: string) => React.string(_open) } module C1 = { @react.component - external make: (@as("open") ~_open: string) => React.element = "default" + external make: (@as("open") ~_open: string, @as("type") ~_type: string) => React.element = + "default" } -let c0 = -let c1 = +let c0 = +let c1 = From 925325afbb938a34b58c8f08e757c2392cc518cd Mon Sep 17 00:00:00 2001 From: Woonki Moon Date: Wed, 14 Dec 2022 01:50:46 +0900 Subject: [PATCH 3/7] update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a109a16b62..c0a336ff59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -70,6 +70,7 @@ These are only breaking changes for unformatted code. - Prevent inlining of async functions in additional cases https://github.com/rescript-lang/rescript-compiler/issues/5860 - Fix build error where aliasing arguments to `_` in the make function with JSX V4. https://github.com/rescript-lang/rescript-compiler/pull/5881 - Fix parsing of spread props as an expression in JSX V4 https://github.com/rescript-lang/rescript-compiler/pull/5885 +- Fix dropping attributes from props in make function in JSX V4 https://github.com/rescript-lang/rescript-compiler/pull/5905 # 10.1.0 From 464a9b18812bfa6acec278b9e1c9b461b3b156ac Mon Sep 17 00:00:00 2001 From: Woonki Moon Date: Wed, 14 Dec 2022 09:18:01 +0900 Subject: [PATCH 4/7] clean up test --- .../ppx/react/expected/mangleKeyword.res.txt | 36 +++++++++---------- res_syntax/tests/ppx/react/mangleKeyword.res | 24 ++++++------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/res_syntax/tests/ppx/react/expected/mangleKeyword.res.txt b/res_syntax/tests/ppx/react/expected/mangleKeyword.res.txt index ff8804e380..78108dd056 100644 --- a/res_syntax/tests/ppx/react/expected/mangleKeyword.res.txt +++ b/res_syntax/tests/ppx/react/expected/mangleKeyword.res.txt @@ -1,25 +1,25 @@ @@jsxConfig({version: 3}) -module C0 = { +module C30 = { @obj external makeProps: (~_open: 'T_open, ~key: string=?, unit) => {"_open": 'T_open} = "" @react.component let make = @warning("-16") (~_open) => React.string(_open) let make = { - let \"MangleKeyword$C0" = (\"Props": {"_open": 'T_open}) => make(~_open=\"Props"["_open"]) - \"MangleKeyword$C0" + let \"MangleKeyword$C30" = (\"Props": {"_open": 'T_open}) => make(~_open=\"Props"["_open"]) + \"MangleKeyword$C30" } } -module C1 = { +module C31 = { @obj external makeProps: (~_open: string, ~key: string=?, unit) => {"_open": string} = "" external make: React.componentLike<{"_open": string}, React.element> = "default" } -let c0 = React.createElement(C0.make, C0.makeProps(~_open="x", ())) -let c1 = React.createElement(C1.make, C1.makeProps(~_open="x", ())) +let c30 = React.createElement(C30.make, C30.makeProps(~_open="x", ())) +let c31 = React.createElement(C31.make, C31.makeProps(~_open="x", ())) @@jsxConfig({version: 4, mode: "classic"}) -module C0 = { +module C4C0 = { type props<'T_open, 'T_type> = { @as("open") _open: 'T_open, @as("type") _type: 'T_type, @@ -29,12 +29,12 @@ module C0 = { let make = ({@as("open") _open, @as("type") _type, _}: props<'T_open, string>) => React.string(_open) let make = { - let \"MangleKeyword$C0" = (props: props<_>) => make(props) + let \"MangleKeyword$C4C0" = (props: props<_>) => make(props) - \"MangleKeyword$C0" + \"MangleKeyword$C4C0" } } -module C1 = { +module C4C1 = { type props<'T_open, 'T_type> = { @as("open") _open: 'T_open, @as("type") _type: 'T_type, @@ -43,12 +43,12 @@ module C1 = { external make: @as("open") React.componentLike, React.element> = "default" } -let c0 = React.createElement(C0.make, {_open: "x", _type: "t"}) -let c1 = React.createElement(C1.make, {_open: "x", _type: "t"}) +let c4c0 = React.createElement(C4C0.make, {_open: "x", _type: "t"}) +let c4c1 = React.createElement(C4C1.make, {_open: "x", _type: "t"}) @@jsxConfig({version: 4, mode: "automatic"}) -module C0 = { +module C4A0 = { type props<'T_open, 'T_type> = { @as("open") _open: 'T_open, @as("type") _type: 'T_type, @@ -58,12 +58,12 @@ module C0 = { let make = ({@as("open") _open, @as("type") _type, _}: props<'T_open, string>) => React.string(_open) let make = { - let \"MangleKeyword$C0" = (props: props<_>) => make(props) + let \"MangleKeyword$C4A0" = (props: props<_>) => make(props) - \"MangleKeyword$C0" + \"MangleKeyword$C4A0" } } -module C1 = { +module C4A1 = { type props<'T_open, 'T_type> = { @as("open") _open: 'T_open, @as("type") _type: 'T_type, @@ -72,5 +72,5 @@ module C1 = { external make: @as("open") React.componentLike, React.element> = "default" } -let c0 = React.jsx(C0.make, {_open: "x", _type: "t"}) -let c1 = React.jsx(C1.make, {_open: "x", _type: "t"}) +let c4a0 = React.jsx(C4A0.make, {_open: "x", _type: "t"}) +let c4a1 = React.jsx(C4A1.make, {_open: "x", _type: "t"}) diff --git a/res_syntax/tests/ppx/react/mangleKeyword.res b/res_syntax/tests/ppx/react/mangleKeyword.res index c40da3b4f1..2e0fa7c344 100644 --- a/res_syntax/tests/ppx/react/mangleKeyword.res +++ b/res_syntax/tests/ppx/react/mangleKeyword.res @@ -1,45 +1,45 @@ @@jsxConfig({version: 3}) -module C0 = { +module C30 = { @react.component let make = (~_open) => React.string(_open) } -module C1 = { +module C31 = { @react.component external make: (~_open: string) => React.element = "default" } -let c0 = -let c1 = +let c30 = +let c31 = @@jsxConfig({version: 4, mode: "classic"}) -module C0 = { +module C4C0 = { @react.component let make = (@as("open") ~_open, @as("type") ~_type: string) => React.string(_open) } -module C1 = { +module C4C1 = { @react.component external make: (@as("open") ~_open: string, @as("type") ~_type: string) => React.element = "default" } -let c0 = -let c1 = +let c4c0 = +let c4c1 = @@jsxConfig({version: 4, mode: "automatic"}) -module C0 = { +module C4A0 = { @react.component let make = (@as("open") ~_open, @as("type") ~_type: string) => React.string(_open) } -module C1 = { +module C4A1 = { @react.component external make: (@as("open") ~_open: string, @as("type") ~_type: string) => React.element = "default" } -let c0 = -let c1 = +let c4a0 = +let c4a1 = From 196493893c021431607510749b5387a2e0333bc3 Mon Sep 17 00:00:00 2001 From: woonki Date: Fri, 16 Dec 2022 01:13:00 +0900 Subject: [PATCH 5/7] update CHANGELOG.md --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c0a336ff59..40a1414e78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,6 +61,11 @@ These are only breaking changes for unformatted code. # 10.1.1 +#### :boom: Breaking Change + +- The prop names duplicated to keyword are not mangled automatically in JSX v4. + - Use `@as` instead + #### :rocket: New Feature - Add support for empty inlined record literal `{}` for inlined records where all fields are optional https://github.com/rescript-lang/rescript-compiler/pull/5900 From 446c18ab3ead7dc37cee9ce36c64fc064f98067a Mon Sep 17 00:00:00 2001 From: woonki Date: Fri, 16 Dec 2022 01:34:25 +0900 Subject: [PATCH 6/7] update CHANGELOG.md --- CHANGELOG.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 40a1414e78..c45f448a6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,11 +61,6 @@ These are only breaking changes for unformatted code. # 10.1.1 -#### :boom: Breaking Change - -- The prop names duplicated to keyword are not mangled automatically in JSX v4. - - Use `@as` instead - #### :rocket: New Feature - Add support for empty inlined record literal `{}` for inlined records where all fields are optional https://github.com/rescript-lang/rescript-compiler/pull/5900 @@ -79,6 +74,11 @@ These are only breaking changes for unformatted code. # 10.1.0 +#### :boom: Breaking Change + +- The prop names duplicated to keyword are not mangled automatically in JSX v4. + - Use `@as` instead + #### :bug: Bug Fix - Fix issue where no error was reported when ? was used for non-optional fields. https://github.com/rescript-lang/rescript-compiler/pull/5853 From 8551b46d4c6147d18822db00b07ca4eeef6815bb Mon Sep 17 00:00:00 2001 From: woonki Date: Fri, 16 Dec 2022 01:44:07 +0900 Subject: [PATCH 7/7] Revert "update CHANGELOG.md" This reverts commit 446c18ab3ead7dc37cee9ce36c64fc064f98067a. --- CHANGELOG.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c45f448a6c..40a1414e78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,6 +61,11 @@ These are only breaking changes for unformatted code. # 10.1.1 +#### :boom: Breaking Change + +- The prop names duplicated to keyword are not mangled automatically in JSX v4. + - Use `@as` instead + #### :rocket: New Feature - Add support for empty inlined record literal `{}` for inlined records where all fields are optional https://github.com/rescript-lang/rescript-compiler/pull/5900 @@ -74,11 +79,6 @@ These are only breaking changes for unformatted code. # 10.1.0 -#### :boom: Breaking Change - -- The prop names duplicated to keyword are not mangled automatically in JSX v4. - - Use `@as` instead - #### :bug: Bug Fix - Fix issue where no error was reported when ? was used for non-optional fields. https://github.com/rescript-lang/rescript-compiler/pull/5853