Skip to content

Commit 1171e16

Browse files
committed
explicit error message for optional component props, since they have another syntax
1 parent f2d3278 commit 1171e16

File tree

5 files changed

+83
-1
lines changed

5 files changed

+83
-1
lines changed

compiler/ml/error_message_utils.ml

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ let print_extra_type_clash_help ~extract_concrete_typedecl ~env loc ppf
426426
single JSX element.@,"
427427
(with_configured_jsx_module "array")
428428
| _ -> ())
429-
| ( Some (RecordField {optional = true; field_name}),
429+
| ( Some (RecordField {optional = true; field_name; jsx = None}),
430430
Some ({desc = Tconstr (p, _, _)}, _) )
431431
when Path.same Predef.path_option p ->
432432
fprintf ppf
@@ -444,6 +444,24 @@ let print_extra_type_clash_help ~extract_concrete_typedecl ~env loc ppf
444444
@{<info>{%s: ?%s@}}"
445445
field_name field_name
446446
(Parser.extract_text_at_loc loc)
447+
| ( Some (RecordField {optional = true; field_name; jsx = Some _}),
448+
Some ({desc = Tconstr (p, _, _)}, _) )
449+
when Path.same Predef.path_option p ->
450+
fprintf ppf
451+
"@,\
452+
@,\
453+
@{<info>%s@} is an optional component prop, and you're passing an \
454+
optional value to it.@,\
455+
Values passed to an optional component prop don't need to be wrapped in \
456+
an option. You might need to adjust the type of the value supplied.\n\
457+
\ @,\
458+
Possible solutions: @,\
459+
- Unwrap the option from the value you're passing in@,\
460+
- If you really do want to pass the optional value, prepend the value \
461+
with @{<info>?@} to show you want to pass the option, like: \
462+
@{<info>%s=?%s@}"
463+
field_name field_name
464+
(Parser.extract_text_at_loc loc)
447465
| ( Some (FunctionArgument {optional = true}),
448466
Some ({desc = Tconstr (p, _, _)}, _) )
449467
when Path.same Predef.path_option p ->
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
2+
We've found a bug for you!
3+
/.../fixtures/jsx_custom_component_optional_prop.res:33:34
4+
5+
31 │ let o = Some(1.)
6+
32 │
7+
33 │ let x = <CustomComponent someOpt=o />
8+
34 │
9+
10+
This has type: option<float>
11+
But the component prop someOpt is expected to have type: float
12+
13+
someOpt is an optional component prop, and you're passing an optional value to it.
14+
Values passed to an optional component prop don't need to be wrapped in an option. You might need to adjust the type of the value supplied.
15+
16+
Possible solutions:
17+
- Unwrap the option from the value you're passing in
18+
- If you really do want to pass the optional value, prepend the value with ? to show you want to pass the option, like: someOpt=?o
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
We've found a bug for you!
3+
/.../fixtures/jsx_custom_component_type_mismatch.res:31:34-40
4+
5+
29 │ }
6+
30 │
7+
31 │ let x = <CustomComponent someOpt="hello" />
8+
32 │
9+
10+
This has type: string
11+
But the component prop someOpt is expected to have type: float
12+
13+
You can convert string to float with Float.fromString.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
@@config({
2+
flags: ["-bs-jsx", "4"],
3+
})
4+
5+
module React = {
6+
type element = Jsx.element
7+
type componentLike<'props, 'return> = 'props => 'return
8+
type component<'props> = Jsx.component<'props>
9+
10+
@module("react/jsx-runtime")
11+
external jsx: (component<'props>, 'props) => element = "jsx"
12+
13+
type fragmentProps = {children?: element}
14+
@module("react/jsx-runtime") external jsxFragment: component<fragmentProps> = "Fragment"
15+
16+
external float: float => element = "%identity"
17+
}
18+
19+
module CustomComponent = {
20+
@react.component
21+
let make = (~someOpt=?) => {
22+
React.float(
23+
switch someOpt {
24+
| Some(5.) => 1.
25+
| _ => 2.
26+
},
27+
)
28+
}
29+
}
30+
31+
let o = Some(1.)
32+
33+
let x = <CustomComponent someOpt=o />

0 commit comments

Comments
 (0)