Skip to content

Instantly share code, notes, and snippets.

@kuroski
Last active March 28, 2024 18:32
Show Gist options
  • Star 22 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save kuroski/9a7ae8e5e5c9e22985364d1ddbf3389d to your computer and use it in GitHub Desktop.
Save kuroski/9a7ae8e5e5c9e22985364d1ddbf3389d to your computer and use it in GitHub Desktop.
Typescript type camelCase / snake_case conversion
type CamelCase<S extends string> = S extends `${infer P1}_${infer P2}${infer P3}`
? `${Lowercase<P1>}${Uppercase<P2>}${CamelCase<P3>}`
: Lowercase<S>
type KeysToCamelCase<T> = {
[K in keyof T as CamelCase<string & K>]: T[K]
}
type CamelToSnakeCase<S extends string> = S extends `${infer T}${infer U}` ?
`${T extends Capitalize<T> ? "_" : ""}${Lowercase<T>}${CamelToSnakeCase<U>}` :
S
type KeysToSnakeCase<T> = {
[K in keyof T as CamelToSnakeCase<string & K>]: T[K]
}
@starmut
Copy link

starmut commented Jun 13, 2021

I was using type KeysToSnakeCase, passing it an object that already has snake case results in it having 2 underscores:

example

@kimskovhusandersen
Copy link

kimskovhusandersen commented Dec 6, 2022

You can define a type that removes the first character if it's an underscore and utilize that

type RemoveUnderscoreFirstLetter<S extends string> =
  S extends `${infer FirstLetter}${infer U}`
    ? `${FirstLetter extends "_" ? U : `${FirstLetter}${U}`}`
    : S;

type CamelToSnakeCase<S extends string> =
  S extends `${infer T}${infer U}`
    ? `${T extends Capitalize<T> ? "_" : ""}${RemoveUnderscoreFirstLetter<
        Lowercase<T>
      >}${CamelToSnakeCase<U>}`
    : S;

type KeysToSnakeCase<T extends object> = {
  [K in keyof T as CamelToSnakeCase<K & string>]: T[K];
};

@latel
Copy link

latel commented Jun 14, 2023

image
Parsing error: Type expected.eslint

@prodoxx
Copy link

prodoxx commented Jun 21, 2023

This doesn't work for objects keys in arrays like this:

const data = {
  name: 'Rocket',
  parts: [ { brandName: 'starx' }]
}

@harrytran998
Copy link

Thanks for sharing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment