Created
September 21, 2021 04:03
-
-
Save steven-schmoll-at/1ce3538691b5814e94b6ccea1912e673 to your computer and use it in GitHub Desktop.
A typescript utility type to convert snake_case keys of an interface, to camelCase
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Converts a type string from a snake_case string to PascalCase. | |
* This will convert all snake case strings including strings with no underscores, or many | |
*/ | |
export type PascaleFromSnake<String extends string> = String extends `${infer First}_${infer Rest}` ? `${Capitalize<Lowercase<First>>}${PascaleFromSnake<Rest>}` : Capitalize<Lowercase<String>> | |
/** | |
* Converts a type string from a snake_case string to camelCase. | |
* This will convert all snake case strings including strings with no underscores, or many | |
*/ | |
export type CamelFromSnake<String extends string> = String extends `${infer First}_${infer Rest}` ? `${Lowercase<First>}${PascaleFromSnake<Rest>}` : Lowercase<String> | |
type InternalMapCamelKeys<T, deep extends boolean> = { | |
[key in keyof T & string]: { | |
[transformed in CamelFromSnake<key & string>]: deep extends true ? SnakeToCamelKeys<T[key], deep> : T[key] | |
} | |
} | |
// Creates a union of all value types within the map. This is used to extract out the values from above | |
type CombineAll<T> = T extends {[name in keyof T]: infer Type} ? Type : never | |
/** | |
* Transforms an object with snake_case keys to an object with camelCase keys. | |
* | |
* If deep is true, this also transforms the keys of internal classes too. | |
*/ | |
export type SnakeToCamelKeys<T, deep extends boolean = false> = T extends object ? CombineAll<InternalMapCamelKeys<T, deep>> : T | |
// Example | |
//======================== | |
interface Test { | |
name: string | |
other_name: string | |
some_other: { | |
with_inside: boolean | |
name: string | |
} | |
} | |
const exampleWithoutInner: SnakeToCamelKeys<Test> = { | |
name: 'Test', | |
otherName: 'Something else', | |
someOther: { | |
with_inside: false, | |
name: 'Inside' | |
} | |
} | |
const exampleWithInner: SnakeToCamelKeys<Test, true> = { | |
name: 'Test', | |
otherName: 'Something else', | |
someOther: { | |
withInside: true, | |
name: 'Inside' | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment