typescript - วิธีการดึงคีย์ทั้งหมดของวัตถุซ้อนกันแบบเรียกซ้ำ?
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>
เป็นผลให้ฉันมี:
type Test = { keys: 'amount' | 'error' | 'data' | ... }
แต่ฉันต้องได้:
type Test = { keys: 'amount' | 'error' | 'data' | 'rows' | 'messages' | 'goodNews' | 'badNews'}
คำตอบ #1
ดูเหมือนว่าคุณต้องการบางอย่างแบบนี้:
type RecursiveKeyof<T> = T extends object ? (
T extends readonly any[] ? RecursiveKeyof<T[number]> : (
keyof T | RecursiveKeyof<T[keyof T]>
)
) : never
นี่จะเรียกซ้ำลงไปในประเภทวัตถุ ให้คุณได้คีย์ของคุณสมบัติย่อยทั้งหมดและคุณสมบัติย่อย-ย่อย เป็นต้น มันจะละเว้นค่าพื้นฐาน (ดังนั้นจึงไม่มี keyof string) และกรณีพิเศษของอาร์เรย์เพื่อให้คุณได้คีย์ของ องค์ประกอบ ของอาร์เรย์เท่านั้น ไม่ใช่อาร์เรย์เอง (ซึ่งมีคีย์เช่น number และ "push", "pop" เป็นต้น)
ดูเหมือนว่า AllKeys ของคุณต้องการคุณสมบัติ keys ดังนั้นเราจึงสามารถเขียนมันได้แบบนี้:
type AllKeys<T> = { keys: RecursiveKeyof<T> }
มาลองดูว่ามันใช้ได้ไหม:
type Test = AllKeys<NestedObject>
// type Test = {keys: "amount" | "error" | "data" | "rows" | "messages" | "goodNews" | "badNews" }
ดูดี
ลิงก์ Playground ไปยังโค้ด
คำตอบ #2
นี่ใช้ได้:
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>
นี่คือสนามเด็กเล่นของฉัน
