編輯:代碼游樂場
這是檢查傳遞給我的函式的資料庫物體是否具有所有必需連接的實際代碼:
export const checkEntitiesAreJoined = <Type>(baseEntity: Type, keysOfEntitiesToCheck: (keyof Type)[]) => {
keysOfEntitiesToCheck.forEach((key) => {
if (!baseEntity[key]){
throw new Error(`
Some tables haven't been joined!
Expected keys:
${keysOfEntitiesToCheck.join(', ')}
Entity keys:
${Object.keys(baseEntity).join(', ')}`
)
}
})
}
它需要一個物體和欄位來檢查,如果其中任何一個未定義,則會引發錯誤。以這種方式制作它是因為它用于許多不同的物體,因此逐個欄位顯式檢查將是愚蠢的。我如何使用它以及問題是什么:
const entity: {
relation_1: string | undefined
relation_2: string | undefined
} = someAssignedValue
checkEntitiesAreJoined(entity, ["relation_1","relation_2"])
doSomething(entity.relation_1) // entity.relation_1 is still string | undefined here
如果我明確地檢查了 entity.relation_1 ,例如:
if(!entity.relation_1) throw new Error("error")
TS 會意識到 entity.relation_1 不能在代碼中進一步未定義,但我實作的更通用的版本并沒有這樣做。我知道我可以使用像 entity.relation_1 這樣的非空斷言!但我們有一個禁止這樣做的 eslint 規則。有沒有一種干凈的方法來撰寫像我想要的那樣的通用函式并告訴 TS 作為引數傳遞的欄位不能為空/未定義?我正在考慮回傳具有轉換型別的實際值,但我不知道如何告訴 TS 這個回傳值與 baseEntity 輸入引數具有相同的型別,但是與 keysOfEntitiesToCheck 的值匹配的欄位可以不再虛偽。我也愿意采用不同的方法來檢查這一點,以實作相同的目標。
請注意,當我知道傳遞給 checkEntitiesAreJoined 的物體的格式時,我知道如何執行此操作,我正在尋找一種通用的方法來執行此操作,即無需知道 baseEntity 可以擁有哪些鍵。我也無法回傳Required,因為未檢查的其他鍵可能仍然是虛假的。
uj5u.com熱心網友回復:
asserts在 TypeScript 中使用型別保護之前的斷言實際上是可能的:
function checkEntitiesAreJoined
<Type, Keys extends (keyof Type)[]>
(baseEntity: Type, keysOfEntitiesToCheck: Keys):
asserts baseEntity is Omit<Type, Keys[number]> & {
[K in Keys[number]]-?: Exclude<Type[K], undefined>
} {
// ...
}
你會注意到它checkEntitiesAreJoined現在是一個命名函式(這是必需的),它看起來像一個型別保護,但asserts在通常的X is Y.
checkEntitiesAreJoined(entity, ['example_relation'])
// from this point on, 'entity' is Omit<ExampleEntityType, "example_relation"> & { example_relation: string }
// not affected
entity.something_else
// and it works
return entity.example_relation // string
一個很酷的小操場展示了這一點
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/477934.html
標籤:打字稿
上一篇:建構式作為物件鍵
