我有一些物件:
const obj = { age: 25, name: "Michal", gender: "Male" }
type Object = typeof obj
然后,我有型別助手,它將從此物件回傳指定屬性的型別:
type Value<Key extends keyof Object> = Object[Key]
Value<"age"> // number
如果KeyinValue也可以是無效的,我應該怎么做?像這樣的東西:
type Value<Key extends void | keyof Object> = Key extends void ? never : Object[Key]
但它不起作用并出現錯誤:
型別“鍵”不能用于索引型別“物件”
我該如何解決?
uj5u.com熱心網友回復:
這是目前 TypeScript 的設計限制或缺失功能;有關相關問題,請參閱microsoft/TypeScript#48710和 microsoft/ TypeScript#26240 (可能還有其他)。
形式的條件型別T extends U ? TrueBranch<T> : FalseBranch<T>可以將型別縮小到trueT分支中的約束 ,變成類似. 但是在假分支中沒有任何縮小。TypeScript 沒有表單的否定型別(這是在microsoft/TypeScript#29317中實作的,但從未發布過),因此在一般情況下 無法表達。UTrueBranch<T & U>not UFalseBranch<T & not U>
(在一般情況下,它甚至不是真的;考慮(0 | "") extends (number | string) is true, but (0 | "") extends number is false... but this does not imply that(0 | "") extends string`。)
您只需獲得FalseBranch<T>原始的、未縮小的T. 在T和U都是文字型別的聯合的特定情況下,您可以過濾到類似的東西,但這還沒有實作。TExclude<T, U>
幸運的是,有一些解決方法。在像您這樣的情況下,您只需要真正Key縮小到keyof Object; 你不關心縮小到void,因為你生產neverif Keyis void。您可以簡單地反轉檢查的意義,使真分支和假分支位于不同的位置:
type Value<Key extends void | keyof Object> =
Key extends keyof Object ? Object[Key] : never; // okay
當然,在某些情況下,您確實需要在真分支和假分支中都縮小范圍,因此您不能簡單地交換您正在檢查的內容:
type Foo = { x: string, y: number };
type Bar = { a: string, b: number };
type BazBad1<K extends keyof Foo | keyof Bar> =
K extends keyof Foo ? Foo[K] : Bar[K]; // error!
type BazBad2<K extends keyof Foo | keyof Bar> =
K extends keyof Bar ? Bar[K] : Foo[K]; // error!
在這些情況下,您可以添加冗余檢查以獲得所需的行為:
type Baz<K extends keyof Foo | keyof Bar> =
K extends keyof Foo ? Foo[K] :
K extends keyof Bar ? Bar[K] :
never; // okay
Playground 代碼鏈接
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/468682.html
標籤:打字稿
下一篇:縮小映射函式的泛型型別
