[英]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 時,編譯器會理解name
和value
之間的關系。但是通過檢查實現中的name
來縮小value
的類型目前是不可能的,至少當name
和value
是泛型類型時。
我們可以刪除泛型類型並為參數構造一個聯合類型。
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
元組充當可區分的聯合,編譯器可以通過檢查name
的value
來適當縮小值的類型。
如果您仍然需要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.