POC of giving a type-error for non keyed elements when are under React.array#812
POC of giving a type-error for non keyed elements when are under React.array#812
Conversation
| type component('props) = componentLike('props, element); | ||
| type element('a); /* 'a captures any type information to differenciate with others 'a's */ | ||
|
|
||
| type keyed; /* Flag to mark element('a) to be keyed */ |
There was a problem hiding this comment.
just a note, I think this won't work correctly after ocaml/ocaml#8900
There was a problem hiding this comment.
Totally, we can workaround it by adding "private" fields:
type keyed = private Tag_keyed
type non_keyed = private Tag_non_keyed
|
I need to look at this thoroughly, but one thing that obviously becomes harder is annotating since there's the new phantom type variable for |
|
cc @mlms13 @maxkorp @andywhite37 @endlo would love your input on this if you can. |
|
I started testing the approach in #813 (which is in the end very similar to this 😄 ) and noticed a case in reshowcase that breaks. The code breaks here with this error: The code does something like this: Array.map(((entityName, entity)) => {
let searchMatchingTerms =
HighlightTerms.getMatchingTerms(~searchString, ~entityName);
let isEntityNameMatchSearch =
searchString == "" || searchMatchingTerms->Belt.Array.size > 0;
switch (entity) {
| Demo(_) =>
if (isEntityNameMatchSearch || parentCategoryMatchedSearch) {
<Link
key=entityName
...
/>;
} else {
React.null;
}
...I think the error makes sense. I am not sure what the fix should be. React supports |
|
I believe this is a bug in our code, right? An array of elements where some of them are null seems a bad JSX construction. I have coded myself worst atrocities and later filtering out React.nulls. |
|
True. Splitting the processing in 2 steps:
solves the issue. See ahrefs/reshowcase@68718ce for the fix (it includes another fix for unneeded |
|
Another interesting case I found is [@react.component]
let make = (~children) =>
<ol>
{children->React.Children.mapWithIndex((element, index) =>
<li key={string_of_int(index)}> element </li>
)}
</ol>;I fixed it in 29fc9be. I spent some time applying the typed keys to ahrefs monorepo, I am far from finished but I found already 5 bugs of elements that were missing keys. There were also 10+ places where keys were added unnecessarily. I think the largest pain points are:
In general, my impression is that this improvement could be very useful, and once folks get used to how the types work, the advantages would overcome the downsides. @davesnx @johnhaley81 thanks for proposing it! ❤️ |
|
Ah, another thing I forgot is that https://react.dev/reference/react/Children
|
That's very suspicious, people rarely add keys without a good reason. |

Introduced an idea where there's a difference between elements/components with keys. Useful for the type-checker to raise an issue where keys aren't passed, but React.array needs them.
The implementation of the types goes as follow:
So all usages of
element_without_keyandelement_with_keycan be explicit on the bindings.@johnhaley81
Pros of this PR
Example of the type error:
Cons