// ref: https://github.com/microsoft/TypeScript/pull/40336#issuecomment-684122600 export type StrSplit = string extends S ? string[] : S extends `${infer T}${D}${infer U}` ? [T, ...StrSplit] : [S] type V = string | number | boolean | bigint export type TupleJoin = T extends [] ? '' : // @ts-ignore T extends [unknown] ? `${T[0]}` : // @ts-ignore T extends [unknown, ...infer U] ? `${T[0]}${D}${TupleJoin}` : string // export type StrJoin = // T extends [] ? '' : // T extends [V] ? `${T[0]}`: `${T[0]}${D}${StrJoin, D>}` // type FormatCapitalize = // T extends [] ? [] : // T extends [string] ? [`${Capitalize}`] : // T extends [string, ...infer U] ? [`${Capitalize}`, ...FormatCapitalize] : [] // type FormatCamelCase = // T extends [] ? [] : // T extends [unknown] ? [T[0]] : // T extends [unknown, ...infer U] ? [T[0], ...FormatCapitalize] : [] // export type SnakeToCamel = TupleJoin>, ''> // export type SnakeToPascal = TupleJoin>, ''> export type Digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' export type CamelToSnake< T extends string, D extends string = '_' > = string extends D ? never : T extends `${infer F extends D}${infer R}` ? `${F}${_CamelToSnake}` : _CamelToSnake extends `${D}${infer U}` ? U : _CamelToSnake type _CamelToSnake = T extends `${infer U}${infer Rest}` ? U extends D | Digit ? `${U}${_CamelToSnake}` : Uppercase extends U ? `${D}${Lowercase}${_CamelToSnake}` : `${U}${_CamelToSnake}` : Lowercase export type SnakeToCamel< T extends string, D extends string = '_', > = string extends D ? never : T extends `${infer F extends D}${infer R}` ? `${F}${SnakeToCamel}` : _SnakeToCamel // type _SnakeToCamelWoTailing = T extends `${infer U}${infer R}` // ? U extends D // ? `${_SnakeToCamelWoTailing, D>}` // : `${U}${_SnakeToCamelWoTailing}` // : T // type SnakeToCamelNoPrefix< // T extends string, // D extends string = '_' // > = string extends D ? never : TrimStart<_SnakeToCamelWithTailing, D> // type SnakeToCamelNoSuffix< // T extends string, // D extends string = '_' // > = string extends D ? never : TrimEnd<_SnakeToCamelWithTailing, D> type _SnakeToCamel = _SnakeToCamelWithTailing type _SnakeToCamelWithTailing = T extends `${infer U}${infer R}` ? R extends '' ? U : U extends D ? `${_SnakeToCamelWithTailing, D>}` extends `${infer U1 extends D | Digit}${infer R1}` ? U1 extends D ? `${U}${U1}${_SnakeToCamelWithTailing, D>}` : `${U}${U1}${_SnakeToCamelWithTailing}` : `${_SnakeToCamelWithTailing, D>}` : `${U}${_SnakeToCamelWithTailing}` : T export type SnakeToPascal< T extends string, D extends string = '_', > = string extends D ? never : T extends `${infer F extends D}${infer R}` ? `${F}${SnakeToPascal}` : _SnakeToCamelWithTailing, D> export type CamelKeys< T, D extends string = '_', Recursive extends boolean = false, > = T extends object ? _CamelKeys : never type _CamelKeys< T, D extends string = '_', Recursive extends boolean = false> = Recursive extends true ? RecursiveCamelKeys : RecordCamelKeys export type RecursiveCamelKeys = { [K in keyof T as K extends string ? `${SnakeToCamel}` : K]: T[K] extends Record ? RecursiveCamelKeys : T[K] } export type RecordCamelKeys = { [K in keyof T as K extends string ? `${SnakeToCamel}` : K]: T[K] } export type PascalKeys< T, D extends string = '_', Recursive extends boolean = false> = T extends object ? _PascalKeys : never type _PascalKeys< T, D extends string = '_', Recursive extends boolean = false> = Recursive extends true ? RecursivePascalKeys : RecordPascalKeys export type RecursivePascalKeys = { [K in keyof T as K extends string ? `${SnakeToPascal}` : K]: T[K] extends Record ? RecursivePascalKeys : T[K] } export type RecordPascalKeys = { [K in keyof T as K extends string ? `${SnakeToPascal}` : K]: T[K] } export type SnakeKeys< T, D extends string = '_', Recursive extends boolean = false> = T extends object ? _SnakeKeys : never type _SnakeKeys< T, D extends string = '_', Recursive extends boolean = false> = Recursive extends true ? RecursiveSnakeKeys : RecordSnakeKeys export type RecursiveSnakeKeys = { [K in keyof T as K extends string ? `${CamelToSnake}` : K]: T[K] extends Record ? RecursiveSnakeKeys : T[K] } export type RecordSnakeKeys = { [K in keyof T as K extends string ? `${CamelToSnake}` : K]: T[K] }