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