I'm trying to create a Generic Forward Ref component
that accepts a value
of generic type
and a render
function that also needs a value
property from that same generic type
.
I get the Typescript error: TS2322: Type 'Product' is not assignable to type 'T'. 'Product' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Draggable'.
TS2322: Type 'Product' is not assignable to type 'T'. 'Product' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Draggable'.
(L34 @ https://github.com/pieterjandebruyne/generic-forward-ref-issue/blob/master/src/GenericForwardRefComponent.tsx )
I already found some posts on stack overflow explaining what and why it could go wrong but still I feel that none of the explanations really apply to this usecase..
I created a public repo to recreate the issue @ https://github.com/pieterjandebruyne/generic-forward-ref-issue
Files that are being used are:
The ultimate goal is that I could also have for example a CategoryRow
(with value of type Category
(that has id: string
)) that I could pass to the GenericForwardRefComponent
Is this something that would be possible or am I just trying to stretch the current limits of React/TS? Also I would love to hear an explanation why this error occurs as I don't see the error that could happen with this implementation. This stackoverflow probably addresses this but I can't figure out why/which part triggers it in my code.. How to fix TS2322: "could be instantiated with a different subtype of constraint 'object'"?
I used the generic forward ref approach I found @ https://dirask.com/posts/React-forwardRef-with-generic-component-in-TypeScript-D6BoRD
You can see that with this inside the function with this header
const x = <T extends Draggable>(
{
dragOverlay,
renderItem,
value
}: GenericForwardedRefComponentProps<T>,
reference: ForwardedRef<HTMLDivElement>
)
you call this function:
return renderItem({
value,
reference
})
If i simplify, the renderItem
has type (value: T) =>...
but then in the body, the type of value is always Product
.
When the function would be called with T = Product
, that would work fine, but consider, that the caller of this function can call the function with T = MyType
like this:
interface MyType extends Draggable {
my_prop: string
}
x<MyType>({ renderItem: (x: MyType) => { x.my_prop }, value: { name: "XXX" } })
You can see, that in the function renderItem
I'm accessing a field, that is not present in the product type. That's why there is this error. I have fulfilled the contract of the function, but the result is that I'm accessing missing fields.
Anyway, the function is called only once, so you can remove the type parameter and like this:
(
{
dragOverlay,
renderItem,
value
}: GenericForwardedRefComponentProps<Product>,
reference: ForwardedRef<HTMLDivElement>
) => {
Then, typescript will be satisfied.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.