import { CamelToSnakeCase } from '../types/utils' import { fromCamelToSnakeCase } from './common' type ToSnakeCaseKeys = { [Property in NonNullable as CamelToSnakeCase< Extract >]: T[Property] } export const toSnakeCaseKeys = >( obj: T, transform: (value: string) => any = (value: string) => value, result: Record = {} ) => { if (Array.isArray(obj)) { result = obj.map((item: any, index: number) => { if (typeof item === 'object') { return toSnakeCaseKeys(item, transform, result[index]) } return item }) } else { Object.keys(obj).forEach((key) => { const newKey = fromCamelToSnakeCase(key) // Both 'object's and arrays will enter this branch if (obj[key] && typeof obj[key] === 'object') { result[newKey] = toSnakeCaseKeys(obj[key], transform, result[newKey]) } else { result[newKey] = transform(obj[key]) } }) } return result as ToSnakeCaseKeys }