typescript - İç içe nesnenin tüm anahtarları nasıl özyinelemeli olarak alınır?
type NestedObject = {
amount: number,
error: string | null,
data: {
rows: [],
messages: {
goodNews: string | null,
badNews: string | null
}
}
}
//trying recursively get all keys
type AllKeys<T, K extends keyof T> =
T extends object ?
T extends infer O ?
{keys: K | AllKeys<O, keyof O> : never
: K
type Test = AllKeys<NestedObject, keyof NestedObject>
sonuç olarak sahip olduğum:
type Test = { keys: 'amount' | 'error' | 'data' | ... }
ama almam gerekiyor:
type Test = { keys: 'amount' | 'error' | 'data' | 'rows' | 'messages' | 'goodNews' | 'badNews'}
Cevap #1
Görünüşe göre sen bunun gibi bir şey istiyorsun:
type RecursiveKeyof<T> = T extends object ? (
T extends readonly any[] ? RecursiveKeyof<T[number]> : (
keyof T | RecursiveKeyof<T[keyof T]>
)
) : never
Bu, nesne türlerine kadar yineleme yapar ve size tüm alt özelliklerin ve alt-alt özelliklerin vb. anahtarlarını verir. İlkel türleri yok sayar (bu yüzden keyof string yoktur) ve dizileri özel durum olarak ele alır; böylece yalnızca dizinin elemanlarının anahtarlarını alırsınız, dizinin kendisini değil (dizinin number ve "push", "pop" vb. gibi anahtarları vardır).
AllKeys görünüyor ki bir keys özelliği istiyor, böylece bunu şu şekilde yazabiliriz:
type AllKeys<T> = { keys: RecursiveKeyof<T> }
İşleyip işlemediğine bakalım:
type Test = AllKeys<NestedObject>
// type Test = {keys: "amount" | "error" | "data" | "rows" | "messages" | "goodNews" | "badNews" }
Güzel görünüyor.
Koda yönelik oyun alanı bağlantısı
Cevap #2
Bu işe yarıyor:
type NestedObject = {
a: number,
b: {
bb: string[],
cc: string,
dd: {
foo: string
bar: {
baz: 'qqq'
}
}
}
}
type AllKeys<O extends object, K = O[keyof O]> =
keyof O
| (
K extends any[]
? never
: K extends object
? AllKeys<K>
: never
)
type Test = AllKeys<NestedObject>
İşte benim oyun alanım.
