{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "deep-key-paths",
  "type": "registry:lib",
  "title": "DeepKeyPaths",
  "description": "A utility type that extracts all nested key paths from an object type as a union of string literals, including array indices in both dot and bracket notation.",
  "dependencies": [],
  "files": [
    {
      "path": "registry/default/lib/deep-key-paths.ts",
      "content": "/**\n * Credit: https://stackoverflow.com/questions/77976781/typescript-type-for-getting-all-nested-key-paths-of-an-object-including-arrays\n */\n\n/**\n * A utility type that extracts all nested key paths from an object type as a union of string literals.\n *\n * Unlike TypeScript's built-in `keyof` which only provides top-level keys, `DeepKeyPaths<T>`\n * recursively traverses the object structure to generate all possible key paths, including:\n * - Nested object properties (e.g., `\"address.street\"`)\n * - Array indices using both dot notation and bracket notation (e.g., `\"hobbies.0\"` and `\"hobbies[0]\"`)\n * - Deeply nested paths (e.g., `\"hobbies[0].name\"`)\n *\n * The type intelligently handles arrays by excluding array methods (like `push`, `pop`, `map`, etc.)\n * and only including numeric indices for array access.\n *\n * @template T - The object type to extract key paths from\n *\n * @example\n * ```typescript\n * interface Person {\n *   name: string;\n *   address: {\n *     street: string;\n *     city: string;\n *     state: string;\n *   };\n *   hobbies: Array<{\n *     name: string;\n *   }>;\n * }\n *\n * type PersonPaths = DeepKeyPaths<Person>;\n * // Result:\n * // | \"name\"\n * // | \"address\"\n * // | \"address.street\"\n * // | \"address.city\"\n * // | \"address.state\"\n * // | \"hobbies\"\n * // | `hobbies.${number}`\n * // | `hobbies[${number}]`\n * // | `hobbies.${number}.name`\n * // | `hobbies[${number}].name`\n * ```\n *\n * @example\n * ```typescript\n * interface Config {\n *   api: {\n *     baseUrl: string;\n *     timeout: number;\n *   };\n *   features: string[];\n * }\n *\n * type ConfigPaths = DeepKeyPaths<Config>;\n * // Result:\n * // | \"api\"\n * // | \"api.baseUrl\"\n * // | \"api.timeout\"\n * // | \"features\"\n * // | `features.${number}`\n * // | `features[${number}]`\n * ```\n *\n * @remarks\n * This type uses several helper types:\n * - `FixArr<T>`: Removes array methods from array types, keeping only numeric indices\n * - `DeepKeys<T>`: Recursively generates key paths with dot prefixes\n * - `DropInitDot<T>`: Removes the leading dot from generated paths\n *\n * The type handles:\n * - Objects: Recursively extracts all property paths\n * - Arrays: Generates both dot notation (`array.0`) and bracket notation (`array[0]`) for indices\n * - Nested structures: Traverses deeply nested objects and arrays\n * - Primitives: Returns `never` for non-object types\n */\ntype FixArr<T> = T extends readonly unknown[]\n  ? Omit<T, Exclude<keyof unknown[], number>>\n  : T;\n\ntype DeepKeys<T> = T extends object\n  ? {\n      [K in (string | number) & keyof T]: `${\n        | `.${K}`\n        | (`${K}` extends `${number}`\n            ? `[${K}]`\n            : never)}${\"\" | DeepKeys<FixArr<T[K]>>}`;\n    }[(string | number) & keyof T]\n  : never;\n\ntype DropInitDot<T> = T extends `.${infer U}` ? U : T;\n\nexport type DeepKeyPaths<T> = DropInitDot<DeepKeys<FixArr<T>>>;\n",
      "type": "registry:lib"
    }
  ]
}