I have a library function that returns a ref which needs to be passed to some element. The library doesn’t care which type of element it is, so I’d like to type it as React.Ref<HTMLElement>
.
The problem is, assignment rule for refs is backwards. Ref<HTMLElement>
can’t be passed to a div element or any other element for that matter.
If I make the library return Ref<HTMLDivElement>
then it can’t be applied to any other element type.
What’s the correct pattern for that, and why is react ref typed that way?
2
Answers
Try to type it like:
See it on the playground
As I understand it, this is a question of covariance and contravariance.
To oversimplify, covariance means that you can substitute an instance of a more specific type when passing a parameter.
However, function parameters are contravariant:
Refs are more like the function parameters example. The type system doesn’t "know" that a ref is an output-only parameter; in actuality, it’s more like the following:
Unfortunately, I don’t know of a clean solution within TypeScript’s type system. You can resort to typecasts:
Or use generics, as in @moonwave99’s solution.