在 TypeScript 中建立類似於 Keyof 的自定義 Valueof 來返回屬性值型別的聯合
-
在 TypeScript 中使用
valueof
返回屬性值型別的聯合 -
在 TypeScript 中使用
keyof
和typeof
返回屬性值型別的聯合 - 使用 TypeScript 中的單個鍵獲取屬性值型別
- 在 TypeScript 中使用泛型在編譯時檢查鍵值
在本教程中,我們將學習可以用來返回構成屬性或物件的型別的不同方法。
我們可以使用三種方法來實現此功能。其中一種方法利用泛型建立名為 valueof
的自定義型別,該型別返回屬性的所有聯合型別。
第二種方法使用 keyof
和 typeof
型別返回屬性的所有聯合型別。第三種方法根據需要使用單獨的鍵返回單一型別。
我們還將學習在編譯時限制鍵值條目,如果它們不是同一型別,則通過利用泛型和索引訪問型別。
在 TypeScript 中使用 valueof
返回屬性值型別的聯合
轉到 Visual Studio Code 並建立一個名為 typescript-types
的資料夾或使用你喜歡的任何名稱。在資料夾下建立一個名為 value-types-using-valueof.ts
的檔案。
將以下程式碼複製並貼上到 value-types-using-valueof.ts
檔案中。
type ValueOf<T> = T[keyof T];
type Customer = {
firstName: string,
lastName: string,
doB: Date,
}
type ValueOfCustomer = ValueOf<Customer>
let customer: Customer ={
firstName: 'john',
lastName: 'doe',
doB: new Date(2022,12,6),
}
function logDetails(customerInfo: ValueOfCustomer){
console.log(customerInfo)
}
logDetails(customer.firstName)
logDetails(customer.lastName)
logDetails(customer.doB)
logDetails(500)// Error - The union does not include type number
首先,我們定義一個泛型型別 ValueOf<T>
並將其分配給 T[keyof T]
。T
表示任何型別都可以傳遞給 ValueOf
,無論是屬性還是物件。
keyof
返回屬於傳遞型別的所有鍵型別的聯合。
我們建立了包含屬性 firstName
、lastName
和 doB
的 Customer
物件。前兩個屬性是字串型別,最後一個屬性是日期型別。
接下來,我們通過將 Customer
傳遞給 ValueOf<Customer>
泛型型別,建立了一個名為 ValueOfCustomer
的型別。ValueOfCustomer
是我們的新型別,由 Customer
物件中所有關鍵時間的聯合組成。
這意味著 ValueOfCustomer
只能接受型別為字串和日期的值。
為了驗證,我們建立了一個名為 logDetails()
的方法,該方法接受 ValueOfCustomer
型別的引數,並使用它記錄 Customer
的 firstName
、lastName
和 doB
。
請注意,如果我們嘗試在方法中傳遞非字串或日期型別的值,例如數字,我們將收到錯誤,因為方法引數只接受字串或數字。
在 TypeScript 中使用 keyof
和 typeof
返回屬性值型別的聯合
在同一資料夾中,建立一個名為 value-types-using-keyof-and-typeof.ts
的檔案。將以下程式碼複製並貼上到檔案中。
type Customer = {
firstName: string,
lastName: string,
doB: Date,
}
const customer: Customer ={
firstName: 'john',
lastName: 'doe',
doB: new Date(2022,12,6),
} as const
type customertypes = typeof customer[keyof Customer]
function getCustomerInfo(theCustomerTypes: customertypes){
console.log(theCustomerTypes)
}
getCustomerInfo(customer.firstName)
getCustomerInfo(customer.lastName)
getCustomerInfo(customer.doB)
getCustomerInfo(234)//Error - The union does not include type number
在上面的程式碼中,我們定義了包含屬性 firstName
、lastName
和 doB
的 Customer
型別。前兩個屬性是字串型別,最後一個屬性是日期型別。
Customer
物件使用物件中每個屬性的具體值進行初始化。名為 customertypes
的型別已建立並分配給 typeof customer[keyof customer]
。
在最後一個例子中,我們提到 keyof
返回所有鍵型別的聯合。這已經應用到我們的 Customer
物件上來做同樣的事情。
typeof
將返回從 Customer
物件獲取的所有型別,這是在 keyof
的幫助下實現的,如程式碼所示。
為了驗證這一點,我們建立了一個名為 getCustomerInfo()
的方法,該方法接受 customertypes
型別的引數,並使用它來記錄 Customer
物件的值。
請注意,如果我們嘗試傳遞非字串或日期型別的值(例如數字),則在該方法中,我們將收到錯誤訊息,因為新型別不包含型別編號。
使用 TypeScript 中的單個鍵獲取屬性值型別
在上面的兩個示例中,我們已經介紹瞭如何檢索所有值型別的聯合,但在某些情況下,你可能只對一種型別的物件感興趣。
在此示例中,你將學習如何使用單個鍵檢索物件的單個值型別。
在同一資料夾下,建立一個名為 individual-keys.ts
的檔案。將以下程式碼複製並貼上到檔案中。
type Customer = {
firstName: string,
lastName: string,
doB: Date,
}
type date = Customer['doB']
function getDateOfBirth(doB: date): Date{
return doB;
}
let customer: Customer ={
firstName: 'john',
lastName: 'doe',
doB: new Date(2022,12,6),
}
getDateOfBirth(customer.doB)
getDateOfBirth(123)//Error - Method accepts a single parameter of type date
在此示例中,我們重用了與前面示例中相同的客戶定義。日期型別是通過使用 Customer['doB']
引用客戶定義中的 doB
鍵建立的。
這意味著新的 date
型別是 Date 型別。getDateOfBirth()
包含一個 date
型別的引數,並已用於驗證是否只能將日期型別傳遞給它,如程式碼所示。
如果我們嘗試傳遞一個不是 date
型別的值,例如一個數字,我們會得到一個錯誤,因為引數被限制為單一型別。
在 TypeScript 中使用泛型在編譯時檢查鍵值
如前面的示例所示,物件由鍵和值組成。有時我們可能會面臨根據其鍵更改物件值的要求。
在本教程中,我們將學習確保在編譯時檢查我們傳遞的值,以確保它們與鍵的型別相同。
在同一資料夾下建立一個名為 key-value-checking.ts
的檔案。將以下程式碼複製並貼上到檔案中。
type Shipment = {
containerItems: string,
containerSerial: string
shipmentDate: Date
}
declare function updateShipment<K extends keyof Shipment>(key: K, value: Shipment[K]): void;
updateShipment('containerItems','flowers')
updateShipment('containerSerial','def456');
updateShipment('shipmentDate',new Date(2018,3,14))
updateShipment('shipmentDate',1337)// Error- Shipment object does not contain type number
在上面的程式碼中,我們定義了一個名為 Shipment
的物件,其中包含引數 containerItems
、containerSerial
和 shipmentDate
。
前兩個屬性是字串型別,最後一個屬性是日期型別。我們定義了一個名為 updateShipment()
的通用方法。
updateShipment()
方法接受兩個引數,其中一個是鍵,第二個是 Shipment
物件的值。
鍵必須是任何型別的 Shipment
物件鍵,並使用尖括號引數中的 <K extends keyof Shipment>
進行檢查。
由於我們有鍵 K
,我們可以通過使用 Shipment[K]
索引 Shipment
物件的鍵來限制傳遞給該鍵的值。使用此定義,我們為鍵輸入的每個值都必須與鍵的型別相同。
請注意,如果你嘗試傳遞未在 Shipment
物件中定義的值,例如數字,編譯器會標記問題。
David is a back end developer with a major in computer science. He loves to solve problems using technology, learning new things, and making new friends. David is currently a technical writer who enjoys making hard concepts easier for other developers to understand and his work has been published on multiple sites.
LinkedIn GitHub