MediumJavaScriptTypeScript

Recursive Types — Deep Flatten & JSON Keys

TypeScriptRecursionTypes

TypeScript allows recursive type aliases to describe infinitely nested data:

// A deeply nested array of T at any depth:
type NestedArray<T> = T | NestedArray<T>[];

// A JSON-safe value (the canonical recursive type):
type JsonValue =
  | string | number | boolean | null
  | JsonValue[]
  | { [key: string]: JsonValue };

These types mirror recursive *algorithms* — and both must be implemented together.

Your Task

Implement two functions:

deepFlatten(arr)

Recursively flatten a nested array to a 1D array:

deepFlatten([1, [2, [3, [4]]]]) // → [1, 2, 3, 4]
deepFlatten([[1, 2], [3, [4, 5]]]) // → [1, 2, 3, 4, 5]

deepKeys(obj)

Return all leaf key paths in dot-notation from a nested object:

deepKeys({ a: { b: 1, c: { d: 2 } } }) // → ['a.b', 'a.c.d']
deepKeys({ x: 1, y: { z: 2 } })        // → ['x', 'y.z']

Sample tests

Test #1deeply nested array
Input: ["deepFlatten",[1,[2,[3,[4]]]]]
Output: [1,2,3,4]
Test #2mixed nesting
Input: ["deepFlatten",[[1,2],[3,[4,5]]]]
Output: [1,2,3,4,5]
Test #3already flat
Input: ["deepFlatten",[1,2,3]]
Output: [1,2,3]
Test #4nested object keys
Input: ["deepKeys",{"a":{"b":1,"c":{"d":2}}}]
Output: ["a.b","a.c.d"]
Test #5mixed depth keys
Input: ["deepKeys",{"x":1,"y":{"z":2}}]
Output: ["x","y.z"]