簡體   English   中英

獲取嵌套記錄的值類型

[英]Attaining value type of nested record

我想創建一個 function,它可以根據集合名稱操作嵌套記錄的值。 在我的示例代碼中,未獲得值類型:

type Player = { name:string }
type Point = { x:number, y:number }


const collections = {
    players: {} as Record<string, Player>,
    positions: {} as Record<string, Point>,
}

type Collections = typeof collections;


function handleEntity<
    Key extends keyof Collections,
    Col extends Collections[Key],
    Val extends Col[keyof Col],
>(name:Key, value:Val){
    switch(name){
        case 'positions': value.x++ // <-- Not valid :(
    }
}

為什么 Typescript 無法推斷出 Val? 有解決方法嗎?

TypeScript 編譯器通常很難正確縮小通用類型變量的類型。 當您調用 function 時,編譯器會理解namevalue之間的關系。但是通過檢查實現中的name來縮小value的類型目前是不可能的,至少當namevalue是泛型類型時。

我們可以刪除泛型類型並為參數構造一個聯合類型。

function handleEntity(...[name, value]: { 
    [K in keyof Collections]: [K, Collections[K][keyof Collections[K]]] 
  }[keyof Collections]
){
    switch(name){
        case 'positions': value.x++ // properly narrowed :)
    }
}

handleEntity("players", { name: "abc" })
handleEntity("positions", { x: 1, y: 0 })

由於name , value元組充當可區分的聯合,編譯器可以通過檢查namevalue來適當縮小值的類型。

如果您仍然需要handleEntity是通用的,則可以將通用簽名添加為重載。

function handleEntity<
    Key extends keyof Collections,
    Col extends Collections[Key],
    Val extends Col[keyof Col],
>(name:Key, value:Val): void
function handleEntity(...[name, value]: { 
    [K in keyof Collections]: [K, Collections[K][keyof Collections[K]]] 
  }[keyof Collections]
){
    switch(name){
        case 'positions': value.x++ // properly narrowed :)
    }
}

操場

暫無
暫無

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

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