我正在嘗試定義一個可以接收任何型別的型別,它是一個物件,它回傳一個只接受到或的虛線路徑(prop1.prop2.prop3)的型別。到目前為止,這就是我所擁有的:stringstring[]
type MyType<ObjectType extends Record<string, unknown>> = {
[Key in keyof ObjectType & string]: ObjectType[Key] extends Record<
string,
unknown
>
? MyType<ObjectType[Key]> extends ""
? ""
: `${Key}.${MyType<ObjectType[Key]>}`
: ObjectType[Key] extends Array<Record<string, unknown>>
? MyType<Unpacked<ObjectType[Key]>> extends ""
? ""
: `${Key}.${MyType<Unpacked<ObjectType[Key]>>}`
: ObjectType[Key] extends Array<string> | string
? `${Key}`
: "";
}[keyof ObjectType & string];
不好的是,這種型別還回傳型別為stringor的 prop 的父 prop string[]。例如,如果 a 具有以下型別:
type ExampleType = {
detail: {
prop1: string;
subDetail: {
field1: string;
field2: number;
field3: {
inner: string[];
};
field4: number[];
};
};
arrOfObjs: {
name: string;
age: number;
ages: number[];
}[];
};
然后MyType<ExampleType>錯誤地接受arrOfObjs.and detail.subDetail.,但它像預期的那樣接受:arrOfObjs.name,detail.prop1和.detail.subDetail.field1detail.subDetail.field3.inner
誰能指出我錯過了什么?提前感謝您的寶貴時間。
uj5u.com熱心網友回復:
我無法修復您的型別定義,因為它包含Unpacked您在問題中未指定的型別。但是我可以撰寫一種似乎可以實作您想要的型別。
type PathOfString<T, P extends string = ""> = {
[K in keyof T & string]: T[K] extends Record<string, unknown>
? PathOfString<T[K], `${P}${K}.`> extends infer S
? `${S & string}`
: never
: T[K] extends string | string[]
? `${P}${K}`
: T[K] extends Record<string, unknown>[]
? PathOfString<T[K][number], `${P}${K}.`> extends infer S
? `${S & string}`
: never
: never
}[keyof T & string]
這種型別的邏輯很簡單:它是一種遞回型別,遍歷型別T以查找string或string[]離開。我們還有P存盤每個分支路徑的型別。
我們首先映射T映射型別的鍵并為其建立索引[keyof T & string]以創建聯合。
{
[K in keyof T & string]: /* ... */
}[keyof T & string]
因為T[K]我們必須處理三種不同的情況。
T[K]是一個物件。在這里,我們PathOfString通過傳遞T[K]并在末尾附加一個點K來遞回呼叫。P
T[K] extends Record<string, unknown>
? PathOfString<T[K], `${P}${K}.`> extends infer S
? `${S & string}`
: never
: /* ... */
T[K]是任何string一個string[]。在這里,我們可以追加并K回傳P它。
T[K] extends string | string[]
? `${P}${K}`
: /* ... */
T[K]是一個物件陣列。我們基本上做與物件情況相同的事情,但我們將陣列內物件的所有屬性傳遞給PathOfStringwithT[K][number]。
T[K] extends Record<string, unknown>[]
? PathOfString<T[K][number], `${P}${K}.`> extends infer S
? `${S & string}`
: never
: never
您可能想知道為什么這extends infer S是必要的。沒有它,由于某種原因,該型別無法完全評估。如果洗掉它,您可以看到該型別在技術上仍然正確,但不是真正的人類可讀。將滑鼠懸停在此處的型別上以了解我的意思。
讓我們看看它是否有效:
type T0 = PathOfString<ExampleType>
// type T0 = "detail.prop1" | "detail.subDetail.field1" | "detail.subDetail.field3.inner" | "arrOfObjs.name"
在我看來是對的。
操場
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/482446.html
上一篇:如何匯出原型方法?
