簡體   English   中英

在打字稿中過濾keyof類型參數

[英]Filter on keyof type parameter in typescript

無需了解React,只需了解一些背景知識:在我的用例中,我想使用自定義的Higher Order Component來放大用戶指定的React.ComponentClass。 為此,我希望用戶也向我發送我的高階組件將注入的特定道具的名稱列表。 可以這樣做:

function listToComponentProps<TComponentProps, TKey = keyof TComponentProps>(props: Array<TKey>) {
  // Logic here, not important for the example
}
interface TestProps {a: number, b: Function, c: () => number}
listToComponentProps<TestProps>(['a', 'b', 'c'])

keyof關鍵字為我處理約束。 listToComponentProps<TestProps>示例輸入為

  • 有效: ['b']['b', 'c']['c']
  • 無效
    • ['a']['a', 'b']['a', 'b', 'c'] (a是數字,不是函數)
    • ['d']['d', 'c'] (d不屬於接口TestProps

問題是,我要限制的props參數不僅是關鍵TComponentProps ,而且這樣的鍵,在對應類型TComponentPropsFunction (使得'a'將是由編譯器的打字原稿檢測到一個無效選項)。 一個人怎么能完成這樣的任務?

您可以這樣做:

const listToComponentProps = <
  TComponent extends {[P in TKey]: Function },
  TKey extends string = keyof TComponent>
  (props: TKey[]) => { /* ... */ };

interface TestProps {a: number, b: Function, c: () => number}
const result = listToComponentProps<TestProps>(['a', 'b', 'c']) // Type error

這導致類型錯誤:

Type 'TestProps' does not satisfy the constraint '{ a: Function; b: Function; c: Function; }'.
  Types of property 'a' are incompatible.
    Type 'number' is not assignable to type 'Function'.

不幸的是,這種使用默認參數的TComponent最終限制了我們的TComponent僅具有Function屬性。 當您真正想要傳遞類似listToComponentProps<TestProps>(['b', 'c']) ,該內容應該是有效的,您將需要顯式填寫第二個類型參數,即listToComponentProps<TestProps, 'b' | 'c'>(['b', 'c']) listToComponentProps<TestProps, 'b' | 'c'>(['b', 'c'])

真正想要的是不具有缺省參數TKey ,而是用於一般推理,以顆粒狀:在一個類型參數列表, 可以推斷出所有參數(例如TKey ,這可以從傳遞的數組推斷) 推斷,即使必須手動指定一些(在這種情況下為TComponent )。 TypeScript目前無法以這種方式工作,所以我們是SOL。

在TypeScript問題跟蹤器上有很多與此有關的未解決問題,您可以去查找它們並臭氣熏天。


如果良好的推理對您而言比嚴格保留運行時特征更為重要,則可以添加一個虛擬參數來分離兩個類型參數的推理:

const listToComponentProps =
    <TKey extends string>
    (props: TKey[]) =>
    <TComponent extends {[P in TKey]: Function }>
    () => { /* ... */ };

interface TestProps { a: number, b: Function, c: () => number }

const result = listToComponentProps(['a', 'b', 'c'])<TestProps>() // Type error
const result2 = listToComponentProps(['b', 'c'])<TestProps>() // OK

暫無
暫無

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

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