Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add generic type parameter for useFocusZone container ref #5449

Open
iansan5653 opened this issue Dec 16, 2024 · 0 comments · May be fixed by #5468
Open

Add generic type parameter for useFocusZone container ref #5449

iansan5653 opened this issue Dec 16, 2024 · 0 comments · May be fixed by #5468
Labels
enhancement New feature or request react

Comments

@iansan5653
Copy link
Contributor

The type of the containerRef returned from useFocusZone is RefObject<HTMLElement>. This prevents it from being assigned to any actual HTML elements, because HTML element ref prop types are invariant1. If you attempt to do the following you'll get a TypeScript error:

const {containerRef} = useFocusZone()

return <div ref={containerRef}>...</div>
Type 'RefObject<HTMLElement>' is not assignable to type 'LegacyRef<HTMLDivElement> | undefined'.
  Type 'RefObject<HTMLElement>' is not assignable to type 'RefObject<HTMLDivElement>'.
    Property 'align' is missing in type 'HTMLElement' but required in type 'HTMLDivElement'.

Currently the only workaround is a typecast (containerRef as RefObject<HTMLDivElement>) or defining the ref outside the hook using useRef.

This could easily be fixed by adding a generic type parameter to useFocusZone so that the consumer could define an element type to be used, for example:

const {containerRef} = useFocusZone<HTMLDivElement>()

return <div ref={containerRef}>...</div>

Footnotes

  1. This is surprising, but it happens because HTML element ref props accept both object and callback refs. Thus they are typed as (with some simplification) (element: T | null) => void | {current: T | null}. The function type makes T contravariant while the object type makes T covariant, resulting in an invariant type that accepts only exactly T. For more details on covariance and contravariance see the TypeScript documentation.

@lesliecdubs lesliecdubs added the enhancement New feature or request label Dec 17, 2024
@kyooosukedn kyooosukedn linked a pull request Dec 19, 2024 that will close this issue
12 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request react
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants