type IsUpperCase<T extends string> = Lowercase<T> extends T ? false : true;
type SnakeCase<
S extends string,
R extends string = ""
> = S extends `${infer F}${infer Rest}`
? IsUpperCase<F> extends true
? R["length"] extends 0
? SnakeCase<Rest, `${Lowercase<F>}`>
: SnakeCase<Rest, `${R}_${Lowercase<F>}`>
: SnakeCase<Rest, `${R}${F}`>
: R;
type res1 = SnakeCase<"hello">; // => "hello"
type res2 = SnakeCase<"userName">; // => "user_name"
type res3 = SnakeCase<"getElementById">; // => "get_element_by_id"
Solution by Gravity2333 #37268
type Char =
| 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm'
| 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z'
| '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
| '_';
type SnakeCase<T extends string> = T extends `${infer First}${infer Rest}`
? Lowercase<First> extends Char
? First extends Capitalize<First>
? `${Lowercase<First>}${SnakeCaseUtil<Rest>}`
: `${First}${SnakeCaseUtil<Rest>}`
: never
: never
type SnakeCaseUtil<T extends string> = T extends `${infer First}${infer Last}`
? First extends '-'
? Last extends Capitalize<Last>
? SnakeCaseUtil<Last>
: `_${SnakeCaseUtil<Last>}`
: First extends '_'
? Last extends Capitalize<Last>
? SnakeCaseUtil<Last>
: `${First}${SnakeCaseUtil<Last>}`
: First extends Capitalize<First>
? `_${Lowercase<First>}${SnakeCaseUtil<Last>}`
: `${First}${SnakeCaseUtil<Last>}`
: '';
type A = SnakeCase<'abc'>; // abc
type A = SnakeCase<'a-bc-d'>; // a_bc_d
type A = SnakeCase<'ABC'>; // a_b_c
type A = SnakeCase<'a-BA-cD'>; // a_b_a_c_d
type A = SnakeCase<'aBcD'>; // a_bc_d
type A = SnakeCase<'a_a_bc'>; // a_a_bc
type A = SnakeCase<'a_A_dB'>; // a_a_d_b
Solution by motss #37008
export type SnakeCase<S extends string> = S extends `${infer Left}${infer Center}${infer Right}`
? Center extends Uppercase<Center>
? Center extends Lowercase<Center>
? `${Lowercase<Left>}${SnakeCase<`${Center}${Right}`>}`
: `${Lowercase<Left>}_${SnakeCase<`${Center}${Right}`>}`
: `${Lowercase<Left>}${SnakeCase<`${Center}${Right}`>}`
: Lowercase<S>;
Solution by gangnamssal #35863
type SnakeCase<T, R extends string = ''> = T extends `${infer F}${infer L}`
? SnakeCase<L, `${R}${Uppercase<F> extends F ? Lowercase<`_${F}`> : F}`>
: R;
Solution by alexandroppolus #35298
type SnakeCase<S extends string> = S extends `${infer FirstChar}${infer SecondChar}${infer RestChars}`
? `${FirstChar extends '_'
? SecondChar extends '_'
? ''
: FirstChar
: FirstChar extends Capitalize<FirstChar>
? Lowercase<FirstChar>
: SecondChar extends Capitalize<SecondChar>
? SecondChar extends '_'
? FirstChar
: `${FirstChar}_`
: FirstChar}${SnakeCase<`${SecondChar}${RestChars}`>}`
: Lowercase<S>;
Solution by shobande-femi #34681
type SnakeCase<T extends string> = T extends `${infer R}${infer rest}` ? Uppercase<R> extends R ? `_${Lowercase<R>}${SnakeCase<rest>}` : `${R}${SnakeCase<rest>}` : T
Solution by ouzexi #34378
type SnakeCase<T extends string> = type SnakeCase<T extends string> = T extends `${infer Letter}${infer Rest}` ? Uppercase<Letter> extends Letter ? `_${Lowercase<Letter>}${SnakeCase<Rest>}` : `${Letter}${SnakeCase<Rest>}` : '';
Solution by HiiiiD #33128
// ζ―ε¦ζ―ε€§εεζ―
type IsUpperLetter<T extends string> = Uppercase<T> extends Lowercase<T>
? false
: Uppercase<T> extends T
? true
: false;
type SnakeCase<T extends string> = T extends `${infer L}${infer Rest}`
? IsUpperLetter<L> extends true
? `_${Lowercase<L>}${SnakeCase<Rest>}`
: `${L}${SnakeCase<Rest>}`
: "";
Solution by Vampirelee #32708
type UppercaseAZ = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z";
type LowercaseAZ = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z";
type SnakeCondition<
P extends string,
S1 extends string,
S2 extends string
> = S1 extends UppercaseAZ
? P extends "" | "_"
? false
: P extends LowercaseAZ
? true
: S2 extends ""
? false
: S2 extends `${infer C1}${infer C2}`
? C1 extends "_"
? false
: C1 extends LowercaseAZ
? true
: C2 extends LowercaseAZ
? true
: false
: false
: false;
type SnakeKebabTitleFix<S1 extends string> = S1 extends "-" | " " ? "_" : S1;
type SnakeCase<
S extends string,
P extends string = ""
> = S extends `${infer S1}${infer S2}`
? `${SnakeKebabTitleFix<S1> extends "_"
? "_"
: `${SnakeCondition<P, S1, S2> extends true
? `_`
: ""}${Lowercase<S1>}`}${SnakeCase<S2, SnakeKebabTitleFix<S1>>}`
: Lowercase<S>;
The question says camelCase but this supports more than that
Solution by arHSM #30594
type SnakeCase<T> = T extends `${infer A}${infer B}`
? Equal<A, Lowercase<A>> extends true
? `${A}${SnakeCase<B>}`
: `_${Lowercase<A>}${SnakeCase<B>}`
: T
Solution by dreamluo-plus #30469
// your answers
type SnakeCase<T> =
T extends `${infer Head}${infer Rest}`
? Head extends Uppercase<Head>
? `_${Lowercase<Head>}${SnakeCase<Rest>}`
: `${Head}${SnakeCase<Rest>}`
: ''
Solution by 437204933 #29736
type SnakeCase<T extends string> = T extends `${infer First}${infer Rest}`
? First extends Uppercase<First>
? `_${Lowercase<First>}${SnakeCase<Rest>}`
: `${First}${SnakeCase<Rest>}`
: T;
Solution by rldnd #27677
type SnakeCase<T, Res extends string = ''> = T extends `${infer F}${infer R}`
? Uppercase<F> extends F
? SnakeCase<R, `${Res}_${Lowercase<F>}`>
: SnakeCase<R, `${Res}${F}`>
: Res;
Solution by JohnLi1999 #26252
type IsUpper<T extends string> = Uppercase<T> extends Lowercase<T> ? false : Uppercase<T> extends T ? true : false;
type SnakeCase<T extends string> = T extends `${infer F}${infer R}` ? `${IsUpper<F> extends true ? `_${Lowercase<F>}` : F}${SnakeCase<R>}` : ``;
Solution by E-uler #25365
// your answers
type RecursiveSnakeCase<
String extends string,
Result extends string = ''
> = String extends `${infer First}${infer Other}`
? First extends Uppercase<First>
? RecursiveSnakeCase<Other, `${Result}_${Lowercase<First>}`>
: RecursiveSnakeCase<Other, `${Result}${First}`>
: Result;
type SnakeCase<String extends string> = RecursiveSnakeCase<String>;
Solution by thornd17 #24812
type SnakeCase<T extends string, Result extends string = ''> = T extends `${infer First}${infer Rest}`
? Uppercase<First> extends First
? SnakeCase<Rest, `${Result}_${Lowercase<First>}`>
: SnakeCase<Rest, `${Result}${First}`>
: Result
Solution by NeylonR #24733
type SnakeCase<
T extends string,
R extends string = ''
> =
T extends `${infer F}${infer L}`?
F extends Uppercase<F>?
SnakeCase<L,`${R}_${Lowercase<F>}` >
:SnakeCase<L,`${R}${F}` >
:R;
Solution by jiangshanmeta #24480
type SnakeCase<T extends string> =
T extends `${infer F extends string}${infer B extends string}`
? `${F}${B extends Exclude<Capitalize<B>,''>
? `_${Uncapitalize<SnakeCase<B>>}`
: SnakeCase<B>
}`
:T
Solution by Derstilon #24358
// your answers
type SnakeCase<T> = T extends `${infer F}${infer R}` ? Uppercase<F> extends F ?
`_${Lowercase<F>}${SnakeCase<R>}` : `${F}${SnakeCase<R>}` : T
Solution by snakeUni #24293
type SnakeCase<T extends string, R extends string = ''> =
T extends `${infer F}${infer L}`
? SnakeCase<L,`${R}${Uppercase<F> extends F ? `_${Lowercase<F>}`: F}`>
: R extends `_${infer S}` ? S: R
Solution by TKBnice #23621
// your answers
type SnakeCase<T> = T extends `${infer F}${infer R}` ? Uppercase<F> extends F ? `_${Lowercase<F>}${SnakeCase<R>}` : `${F}${SnakeCase<R>}` : T
Solution by jxhhdx #23341
type SnakeCase<T, R extends string = ''> =
T extends `${infer A}${infer Rest}`
? SnakeCase<Rest, `${R}${A extends Uppercase<A> ? '_' : ''}${Lowercase<A>}`>
: R
Solution by drylint #23147
type SnakeCase<S extends string, R extends string = ''>
= S extends `${infer C}${infer T}`
? C extends Lowercase<C> ? SnakeCase<T, `${R}${C}`>
: SnakeCase<T, `${R}_${Lowercase<C>}`>
: R
Solution by teamchong #22547
type IsUppercase<T extends string> = Lowercase<T> extends T ? false : true
type SnakeCase<T extends string, _Pre extends string = ''> =
T extends `${infer F extends string}${infer Rest extends string}`
? IsUppercase<F> extends true
? SnakeCase<Rest, `${_Pre}_${Lowercase<F>}`>
: SnakeCase<Rest, `${_Pre}${F}`>
: _Pre
Solution by zhaoyao91 #22097
type SnakeCase<T extends string> = T extends `${infer First}${infer Rest}` ? (
Rest extends '' ? First : (
First extends Capitalize<First> ? `_${Lowercase<First>}${SnakeCase<Rest>}` : `${First}${SnakeCase<Rest>}`
)
) : never
Solution by CoopTRUE #22058
type SnakeCase<T extends string> =
T extends `${ infer Front }${ infer Rest }`
? Front extends Uppercase<Front>
? `_${ Lowercase<Front> }${ SnakeCase<Rest> }`
: `${ Front }${ SnakeCase<Rest> }`
: ''
Solution by lvjiaxuan #21724
type SnakeCase<T extends string,Result extends string = ""> =
T extends `${infer A}${infer B}`?
A extends Uppercase<A> ?
SnakeCase<B,`${Result}_${Lowercase<A>}`>:
SnakeCase<B,`${Result}${A}`>:
Result
Solution by so11y #21351
// your answers
type SnakeCase<T> = T extends `${infer F}${infer R}` ? F extends Capitalize<F> ? `_${Uncapitalize<F>}${SnakeCase<R>}` : `${F}${SnakeCase<R>}` : T
Solution by YqxLzx #21031
type SnakeCase<T> = T extends `${infer Char}${infer Other}`?
Char extends Uppercase<Char> ?
`_${Lowercase<Char>}${SnakeCase<Other>}`:
`${Char}${SnakeCase<Other>}`
: T
Solution by baian1 #21014
type SnakeCase<T> = T extends `${infer A}${infer R}`
? Uppercase<A> extends A
? `_${Lowercase<A>}${SnakeCase<R>}`
: `${A}${SnakeCase<R>}`
: '';
Solution by bigcreate #20928