@@ -46,6 +46,38 @@ let ref_type loc =
46
46
{loc; txt = Ldot (Ldot (Lident " Js" , " Nullable" ), " t" )}
47
47
[ref_type_var loc]
48
48
49
+ let jsx_element_type ~loc =
50
+ Typ. constr ~loc {loc; txt = Ldot (Lident " Jsx" , " element" )} []
51
+
52
+ let jsx_element_constraint ~loc expr =
53
+ Exp. constraint_ ~loc expr (jsx_element_type ~loc )
54
+
55
+ let rec constrain_jsx_return ~loc expr =
56
+ match expr.pexp_desc with
57
+ | Pexp_fun ({rhs} as desc ) ->
58
+ {
59
+ expr with
60
+ pexp_desc = Pexp_fun {desc with rhs = constrain_jsx_return ~loc rhs};
61
+ }
62
+ | Pexp_newtype (param , inner ) ->
63
+ {
64
+ expr with
65
+ pexp_desc = Pexp_newtype (param, constrain_jsx_return ~loc inner);
66
+ }
67
+ | Pexp_constraint (inner , _ ) ->
68
+ jsx_element_constraint ~loc (constrain_jsx_return ~loc inner)
69
+ | Pexp_let (rec_flag , bindings , body ) ->
70
+ {
71
+ expr with
72
+ pexp_desc = Pexp_let (rec_flag, bindings, constrain_jsx_return ~loc body);
73
+ }
74
+ | Pexp_sequence (first , second ) ->
75
+ {
76
+ expr with
77
+ pexp_desc = Pexp_sequence (first, constrain_jsx_return ~loc second);
78
+ }
79
+ | _ -> jsx_element_constraint ~loc expr
80
+
49
81
let merlin_focus = ({loc = Location. none; txt = " merlin.focus" }, PStr [] )
50
82
51
83
(* Helper method to filter out any attribute that isn't [@react.component] *)
@@ -713,6 +745,10 @@ let map_binding ~config ~empty_loc ~pstr_loc ~file_name ~rec_flag binding =
713
745
vb_match_expr named_arg_list expression
714
746
else expression
715
747
in
748
+ let expression =
749
+ Exp. constraint_ ~loc: binding_loc expression
750
+ (jsx_element_type ~loc: binding_loc)
751
+ in
716
752
(* (ref) => expr *)
717
753
let expression =
718
754
List. fold_left
@@ -784,6 +820,7 @@ let map_binding ~config ~empty_loc ~pstr_loc ~file_name ~rec_flag binding =
784
820
(Some props_record_type, binding, new_binding))
785
821
else if Jsx_common. has_attr_on_binding Jsx_common. has_attr_with_props binding
786
822
then
823
+ let binding_loc = binding.pvb_loc in
787
824
let modified_binding =
788
825
{
789
826
binding with
@@ -839,21 +876,28 @@ let map_binding ~config ~empty_loc ~pstr_loc ~file_name ~rec_flag binding =
839
876
| _ -> Pat. var {txt = " props" ; loc}
840
877
in
841
878
879
+ let applied_expression =
880
+ Exp. apply
881
+ (Exp. ident
882
+ {
883
+ txt =
884
+ Lident
885
+ (match rec_flag with
886
+ | Recursive -> internal_fn_name
887
+ | Nonrecursive -> fn_name);
888
+ loc;
889
+ })
890
+ [(Nolabel , Exp. ident {txt = Lident " props" ; loc})]
891
+ in
892
+ let applied_expression =
893
+ Jsx_common. async_component ~async: is_async applied_expression
894
+ in
895
+ let applied_expression =
896
+ Exp. constraint_ ~loc applied_expression (jsx_element_type ~loc )
897
+ in
842
898
let wrapper_expr =
843
899
Exp. fun_ ~arity: None Nolabel None props_pattern
844
- ~attrs: binding.pvb_expr.pexp_attributes
845
- (Jsx_common. async_component ~async: is_async
846
- (Exp. apply
847
- (Exp. ident
848
- {
849
- txt =
850
- Lident
851
- (match rec_flag with
852
- | Recursive -> internal_fn_name
853
- | Nonrecursive -> fn_name);
854
- loc;
855
- })
856
- [(Nolabel , Exp. ident {txt = Lident " props" ; loc})]))
900
+ ~attrs: binding.pvb_expr.pexp_attributes applied_expression
857
901
in
858
902
859
903
let wrapper_expr = Ast_uncurried. uncurried_fun ~arity: 1 wrapper_expr in
@@ -874,18 +918,20 @@ let map_binding ~config ~empty_loc ~pstr_loc ~file_name ~rec_flag binding =
874
918
| Recursive -> None
875
919
| Nonrecursive ->
876
920
Some
877
- (make_new_binding ~loc: empty_loc ~full_module_name modified_binding)
921
+ (make_new_binding ~loc: binding_loc ~full_module_name modified_binding)
878
922
in
879
923
( None ,
880
924
{
881
925
binding with
882
926
pvb_attributes = binding.pvb_attributes |> List. filter other_attrs_pure;
883
927
pvb_expr =
884
- {
885
- binding.pvb_expr with
886
- (* moved to wrapper_expr *)
887
- pexp_attributes = [] ;
888
- };
928
+ ( binding.pvb_expr |> fun expr ->
929
+ {
930
+ expr with
931
+ (* moved to wrapper_expr *)
932
+ pexp_attributes = [] ;
933
+ }
934
+ |> constrain_jsx_return ~loc: binding_loc );
889
935
},
890
936
new_binding )
891
937
else (None , binding, None )
@@ -934,7 +980,7 @@ let transform_structure_item ~config item =
934
980
(arg.lbl, arg.attrs, return_value.ptyp_loc, arg.typ) :: types )
935
981
| _ -> (full_type, types)
936
982
in
937
- let inner_type , prop_types = get_prop_types [] pval_type in
983
+ let _ , prop_types = get_prop_types [] pval_type in
938
984
let named_type_list = List. fold_left arg_to_concrete_type [] prop_types in
939
985
let ret_props_type =
940
986
Typ. constr ~loc: pstr_loc
@@ -955,7 +1001,7 @@ let transform_structure_item ~config item =
955
1001
let new_external_type =
956
1002
Ptyp_constr
957
1003
( {loc = pstr_loc; txt = module_access_name config " componentLike" },
958
- [ret_props_type; inner_type ] )
1004
+ [ret_props_type; jsx_element_type ~loc: pstr_loc ] )
959
1005
in
960
1006
let new_structure =
961
1007
{
@@ -1046,7 +1092,7 @@ let transform_signature_item ~config item =
1046
1092
(arg.lbl, arg.attrs, return_value.ptyp_loc, arg.typ) :: types )
1047
1093
| _ -> (full_type, types)
1048
1094
in
1049
- let inner_type , prop_types = get_prop_types [] pval_type in
1095
+ let _ , prop_types = get_prop_types [] pval_type in
1050
1096
let named_type_list = List. fold_left arg_to_concrete_type [] prop_types in
1051
1097
let ret_props_type =
1052
1098
Typ. constr
@@ -1067,7 +1113,7 @@ let transform_signature_item ~config item =
1067
1113
let new_external_type =
1068
1114
Ptyp_constr
1069
1115
( {loc = psig_loc; txt = module_access_name config " componentLike" },
1070
- [ret_props_type; inner_type ] )
1116
+ [ret_props_type; jsx_element_type ~loc: psig_loc ] )
1071
1117
in
1072
1118
let new_structure =
1073
1119
{
0 commit comments