我正在嘗試創建多種能夠撰寫的型別:
- MyObjectDetails — 定義 MyObject 結構
- MyObject - 正確遵循這些 MyObjectDetails 的物件。
// Details example
const testObjectDetails: MyObjectDetails = {
name: 'Test',
fields: [
{
name: 'property1'
},
{
name: 'property2'
}
]
}
// Object example
const testObject: MyObject<typeof testObjectDetails> = {
property1: 123,
property3: 456 // Should throw Error -> no such field in the details
// Should throw Error -> property2 is missing
}
我寫了一些代碼,但它們沒有按預期作業:
type MyField = string extends infer T ? Readonly<{
name: T
}> : never
type MyObjectDetails = Readonly<{
name: string,
fields: ReadonlyArray<MyField>
}>
type MyObject<T extends MyObjectDetails> = {
[K in T['fields'][number]['name']]: any;
}
你能幫助我嗎?
uj5u.com熱心網友回復:
這里的問題是testObjectDetails. 您正在使用 type 宣告它MyObjectDetails。執行此操作時,有關特定屬性的所有型別資訊都會丟失,因為MyObjectDetails不包含有關特定屬性名稱的詳細資訊。
解決此問題的一種方法是使用as const和洗掉 type MyObjectDetails。
const testObjectDetails = {
name: 'Test',
fields: [
{
name: 'property1'
},
{
name: 'property2'
}
]
} as const
如果在宣告物件時仍希望具有型別安全性testObjectDetails,則需要使用工廠函式:
const testObjectDetails = createTestObjectDetails({
name: 'Test',
fields: [
{
name: 'property1'
},
{
name: 'property2'
}
]
} as const)
function createTestObjectDetails<T extends MyObjectDetails>(testObjDetails: T) : T{
return testObjDetails
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/480205.html
