我想定義從資料庫下載的物件型別。
type ActiveOrders = {[orderId: string]: {name: string; price: number}}
const activeOrders: ActiveOrders = {
'orderId1': {name: 'apple', price: 123},
'orderId2': {name: 'banana', price: 123},
'orderId3': {name: 'tesla', price: 99999999},
}
以下代碼很好,我的 orderData 保證存在。
for(const orderId in activeOrders) {
const orderData = activeOrders[orderId]
// This is fine, orderData is guaranteed to exist
const {name, price} = orderData
}
這不好,但打字稿沒有給我任何錯誤。someRandomId可以來自任何地方,例如用戶輸入的值。
const orderData2 = activeOrders['someRandomId']
// This is NOT fine, orderData2 is possibly undefined, but typescript says it is guaranteed to exist.
const {name, price} = orderData2
我可以將我的型別更改為跟隨,但我想避免,因為它會弄亂我的 for-in 回圈。
type ActiveOrders = {[orderId: string]: {name: string; price: number} | undefined}
有沒有更優雅的解決方案?
uj5u.com熱心網友回復:
根據定義,TypeScript 將假定您用于訪問此類物件的任何鍵都是有效的,因為您基本上說過它是有效的。
您可以使用noUncheckedIndexedAccess強制打字稿假設在使用任意字串索引物件時結果總是有可能未定義。
您可以使用條件型別來指定何時假定物件始終被定義以及何時可以未定義(或任何真正的東西):
type ActiveOrders = {
[orderId in string|symbol]: orderId extends string ? ({
name: string;
price: number
}|undefined) : {
name: string;
price: number
}
}
const keys : symbol[] = [
Symbol('a'),
Symbol('b'),
Symbol('c')
];
const activeOrders: ActiveOrders = {
[keys[0]]: {
name: 'apple',
price: 123
},
[keys[0]]: {
name: 'banana',
price: 123
},
[keys[0]]: {
name: 'tesla',
price: 99999999
},
}
for(const symbolKey of keys) {
const orderData = activeOrders[symbolKey]
// This is fine, indexed with a symbol the data is assumed to be there
const {name, price} = orderData
}
游樂場鏈接
uj5u.com熱心網友回復:
ActiveOrders您定義的型別如下所示:
// An ActiveOrders is a map...
type ActiveOrders = {
// with arbitrary string keys in it that correspond to map values...
[orderId: string]: {
// that must contain a `name` key whose value is a string
name: string;
// and a `price` key whose value is a number
price: number;
}
};
根據這個定義,activeOrders['someRandomId']是有效的。該ActiveOrders型別允許任何字串鍵存在于其映射中,并且該型別不知道這些鍵將是什么。
使用 TypeScript 4.1 ,您確實可以自由地定義什么是可接受的鍵,但請記住,雖然您可能正在使用 TypeScript 進行編碼,但您的代碼正在被轉換為不再支持您的型別的 JavaScript。
因此,安全檢查每個資料確實取決于您;這些型別只是作為開發人員的護欄。如果你想對資料的形狀進行某種運行時驗證,你可以使用像yup這樣的模式驗證器,但這似乎奇怪地放在 TypeScript 旁邊。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/420727.html
標籤:
