import { snakeCase } from "case-anything" // https://stackoverflow.com/questions/60269936/typescript-convert-generic-object-from-snake-to-camel-case // Typescript magic to convert any string from camelCase to snake_case at compile time type SnakeCase = S extends string ? S extends `${infer T}${infer U}` ? `${T extends Capitalize ? "_" : ""}${Lowercase}${SnakeCase}` : S : S type SnakeCased = { [Property in keyof Type as SnakeCase]: SnakeCased } export default function snakeCaseTree(object: T): SnakeCased { const snakeObject: any = {} for (const key in object) { snakeObject[snakeCase(key, { keepSpecialCharacters: true })] = snakeCaseValue(object[key]) } return snakeObject } function snakeCaseValue(value: any): any { if (typeof value === "object") { if (Array.isArray(value)) { return value.map(snakeCaseValue) } else { return snakeCaseTree(value) } } else { return value } }