首页 > 解决方案 > 如何递归地获取嵌套对象的所有键?

问题描述

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'}

标签: typescriptrecursion

解决方案


看起来你想要这样的东西:

type RecursiveKeyof<T> = T extends object ? (
    T extends readonly any[] ? RecursiveKeyof<T[number]> : (
        keyof T | RecursiveKeyof<T[keyof T]>
    )
) : never

这会递归到对象类型,为您提供所有子属性和子子属性等的键。它忽略原语(所以 no 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 代码链接


推荐阅读