簡體   English   中英

創建一個不可分配給約束的通用 React Forward Ref 組件

[英]Creating a Generic React Forward Ref component unassignable to the constraint

我正在嘗試創建一個Generic Forward Ref component ,它接受generic typevalue和一個render function,它也需要來自相同generic typevalue屬性。

我收到 Typescript 錯誤: 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 )

我已經在堆棧溢出上找到了一些解釋 go 錯誤的原因和原因的帖子,但我仍然覺得沒有任何解釋真正適用於這個用例。

我創建了一個公共回購協議來重現問題@ https://github.com/pieterjandebruyne/generic-forward-ref-issue

正在使用的文件是:

  • App.tsx -> 調用 GenericForwardRefComponent
  • GenericForwardRefComponent.tsx -> 應該呈現 ProductRow 並傳遞通用類型
  • Interfaces.ts -> 所有類型
  • ProductRow.tsx -> 應該呈現的組件

最終目標是我還可以擁有一個CategoryRow (具有 Category type Category的值(具有id: string )),我可以將其傳遞給GenericForwardRefComponent

這是可能的,還是我只是想擴展 React/TS 的當前限制? 我也很想聽聽解釋為什么會發生此錯誤,因為我沒有看到此實現可能發生的錯誤。 這個 stackoverflow 可能解決了這個問題,但我無法弄清楚為什么/哪個部分在我的代碼中觸發了它。 如何修復 TS2322:“可以用約束‘對象’的不同子類型實例化”?

我使用了我在 @ https://dirask.com/posts/React-forwardRef-with-generic-component-in-TypeScript-D6BoRD中找到的通用前向引用方法

你可以在 function 里面看到這個 header

const x = <T extends Draggable>(
        {
            dragOverlay,
            renderItem,
            value
        }: GenericForwardedRefComponentProps<T>,
        reference: ForwardedRef<HTMLDivElement>
    )

你稱之為 function:

        return renderItem({
            value,
            reference
        })

如果我簡化,則renderItem的類型為(value: T) =>...但是在正文中,值的類型始終為Product

當使用T = Product調用 function 時,這會正常工作,但請考慮,此 function 的調用者可以使用T = MyType調用 function,如下所示:

interface MyType extends Draggable {
    my_prop: string
} 
x<MyType>({ renderItem: (x: MyType) => { x.my_prop }, value: { name: "XXX" } })

您可以看到,在 function renderItem中,我正在訪問一個字段,該字段不存在於產品類型中。 這就是為什么會出現這個錯誤。 我履行了function的合同,但結果是訪問缺失字段。

不管怎樣,function 只被調用一次,所以你可以刪除類型參數,像這樣:

    (
        {
            dragOverlay,
            renderItem,
            value
        }: GenericForwardedRefComponentProps<Product>,
        reference: ForwardedRef<HTMLDivElement>
    ) => {

那么,typescript就滿足了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM