tailwindlabs / headlessui

Completely unstyled, fully accessible UI components, designed to integrate beautifully with Tailwind CSS.
https://headlessui.com
MIT License
25.02k stars 1.03k forks source link

`ComboboxOptions` render prop `option` has unknown type #3326

Closed jussirantala closed 1 week ago

jussirantala commented 1 week ago

What package within Headless UI are you using?

For example: @headlessui/react

What version of that package are you using?

For example: v2.1.0

Describe your issue

When using the render prop of ComboboxOptions for a virtualized list, the option property has unknown type.

image
thecrypticace commented 1 week ago

Hey! So this is a known limitation of TypeScript in how it interprets JSX. Children in JSX/TSX can't be "typesafe" and as a result are not able to infer their types, props, etc… based on the parent component.

Matt Pocock has an article about this topic that details some of the problems. But the gist is that we'd need to find a way to design the types such that the "children" of Combobox are only of a certain type — this would then allow us to infer the props type. Sadly this is just not possible today.

This is why the type in the render prop is typed as unknown — to push people to type it themselves. I'd suggest typing it explicitly like this:

<HeadlessComboboxOptions>
  {({ option } : { option: MyOptionType }) => (
    <HeadlessComboboxOption>…</HeadlessComboboxOption>
  )}
</HeadlessComboboxOptions>

Hope that helps 👍

jussirantala commented 1 week ago

@thecrypticace I actually tried to type it myself but I get this:

image

typescript version 5.4.5

jussirantala commented 1 week ago

If the type was any instead of unknown, I think it would work.

thecrypticace commented 1 week ago

I swear worked at one point but yeah aliasing to a different type does not in function argument position. Will get a fixed merged in for that.

thecrypticace commented 1 week ago

I think we're aiming to tag a release today — but if not then tomorrow. 👍

In the meantime you can use our insiders build once it's updated (may take a few minutes):

npm install @headlessui/react@insiders