00114-hard-camelcase

Back

思路:

  1. 处理之前将字符串最小写化,这样就可以统一处理了。使用内置的类型 Lowercase
  2. 遍历字符串,遇到_的情景,将剩下的字符串使用Capitalize首字母大写化,并且去掉_
  3. 在第二步的基础上,需要判断剩下的字符串是否以字母开头的,否则不能去掉 _
type CamelCase<S extends string> = CamelCassLower<Lowercase<S>>;

// 将所有字母转为小写
type CamelCassLower<S extends string> = S extends `${infer Pre}${infer Rest}`
  ? Pre extends "_"
    ? `${IsStartLetter<Rest> extends true ? "" : Pre}${CamelCassLower<
        Capitalize<Rest>
      >}`
    : `${Pre}${CamelCassLower<Rest>}`
  : "";

// 判断一串字符串是否以字母开头
type IsStartLetter<S extends string> = S extends `${infer L}${string}`
  ? Uppercase<L> extends Lowercase<L>
    ? false
    : true
  : false;

Solution by Vampirelee #32607


type CamelCase<S extends string> = S extends Lowercase<S>
  ? S extends `${infer F}_${infer RF}${infer R}`
    ? `${F}${Uppercase<RF>}${CamelCase<R>}`
    : S
  : CamelCase<Lowercase<S>>;
   type camelCase2 = CamelCase<'HELLO_WORLD_WITH_TYPES'> // expected to be same as previous one

Solution by wubrafiq807 #32570

type CamelCase<S extends string, First extends boolean = true, W extends string = ""> = 
  S extends `${infer F}${infer R}`
    ? F extends "_" 
      ? R extends `${infer G}${string}`
        ? Uppercase<G> extends Lowercase<G>
          ? CamelCase<R, First, `${W}_`>
          : First extends true
            ? `${Uncapitalize<Lowercase<W>>}${CamelCase<R, false, "">}`
            : `${Capitalize<Lowercase<W>>}${CamelCase<R, false, "">}`
        : CamelCase<R, First, `${W}${F}`>
      : CamelCase<R, First, `${W}${F}`>
    : First extends true
      ? Uncapitalize<Lowercase<W>>
      : Capitalize<Lowercase<W>>

Solution by vangie #32241

type CamelCase<S extends string, T extends string = Lowercase<S>> = T extends `${infer F}_${infer M}${infer L}`
  ? M extends '_'
    ? `${F}_${CamelCase<`_${L}`>}`
    : M extends '$'
    ? `${F}_${M}${CamelCase<L>}`
    : `${F}${Uppercase<M>}${CamelCase<L>}`

Solution by leejaehyup #31986

type CamelCase<S extends string> = S extends `${infer L}_${infer R1}${infer R2}`
	? Uppercase<R1> extends Lowercase<R1>
		? `${Lowercase<L>}_${CamelCase<`${R1}${R2}`>}`
		: `${Lowercase<L>}${Uppercase<R1>}${CamelCase<R2>}`
	: Lowercase<S>;

Solution by uni-ww #30845

type CamelCase<S extends string> = S extends Lowercase<S>
  ? S extends `${infer F}_${infer RF}${infer R}`
    ? RF extends Uppercase<RF>
      ? `${F}_${CamelCase<`${RF}${R}`>}`
      : `${F}${Uppercase<RF>}${CamelCase<R>}`
    : S
  : CamelCase<Lowercase<S>>;

Solution by DoubleWoodLin #28938

type Alphabet =
  | '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 CapitalizeIfUnderscore<S extends string> = S extends `_${infer W}`
  ? Capitalize<W>
  : S

type StrToLower<T extends string> = T extends `${infer First}${infer Rest}`
  ? First extends Uppercase<Alphabet>
    ? `${Lowercase<First>}${StrToLower<Rest>}`
    : `${First}${StrToLower<Rest>}`
  : ''

type CamelCaseHelper<
  S extends string,
  Buffer extends string = '',
  Result extends string = '',
> = S extends `${infer First}${infer Second}${infer Rest}`
  ? First extends Alphabet
    ? CamelCaseHelper<`${Second}${Rest}`, `${Buffer}${First}`, `${Result}`>
    : First extends '_'
      ? Second extends Alphabet
        ? CamelCaseHelper<
            `${Second}${Rest}`,
            '_',
            `${Result}${CapitalizeIfUnderscore<Buffer>}`
          >
        : CamelCaseHelper<
            `${Second}${Rest}`,
            '',
            `${Result}${CapitalizeIfUnderscore<Buffer>}${First}`
          >
      : CamelCaseHelper<`${Second}${Rest}`, '', `${Result}${First}`>
  : S extends `${infer P}${infer _}`
    ? `${Result}${CapitalizeIfUnderscore<Buffer>}${P}`
    : ''

type CamelCase<S extends string> = CamelCaseHelper<
  StrToLower<S>
> extends `${infer F}${infer R}`
  ? `${Lowercase<F>}${R}`
  : ''

Solution by jazelly #27601

// your answers
type CamelCase<
  S extends string, 
> = 
  S extends `${infer X}_${infer Y}${infer Z}`
  ? Lowercase<Y> extends Uppercase<Y>
    ? `${Lowercase<X>}_${CamelCase<`${Y}${Z}`>}`
    : `${Lowercase<X>}${Uppercase<Y>}${CamelCase<Z>}`
  : Lowercase<S>

Solution by kiki-zjq #26040

type CamelCase<
  S extends string,
  Prev extends string = ''
> = S extends `${infer F}${infer R}`
  ? Uppercase<F> extends Lowercase<F>
    ? `${Prev}${CamelCase<R, F>}`
    : Prev extends '_'
    ? `${CamelCase<R, Uppercase<F>>}`
    : `${Prev}${CamelCase<R, Lowercase<F>>}`
  : Prev;

Solution by JohnLi1999 #25293

// your answers
type IsAlphabet<T extends string> = Lowercase<T> extends Uppercase<T>
    ? false
    : true

type CamelCase<
    S extends string,
    Result extends string = ''
> = S extends `${infer Left}${infer Rest}`
    ? IsAlphabet<Left> extends true
      ? Result extends `${infer Prefix}_`
        ? CamelCase<Rest,`${Prefix}${Uppercase<Left>}`>
        : CamelCase<Rest, `${Result}${Lowercase<Left>}`>
      : CamelCase<Rest, `${Result}${Left}`>
    : Result

Solution by studymachiney #25014

// your answers
type CalGap<S extends string, Gap extends string = ''> = S extends `${infer Left}${infer Rest}`
                                                          ? Uppercase<Left> extends Lowercase<Left>
                                                          ? CalGap<Rest, `${Gap}${Left}`>
                                                          : [Gap, S]
                                                          : [Gap, S]

type Split<T extends string, Res extends string = ''> = T extends `${infer Left}${infer Rest}`
                                ? Uppercase<Left> extends Lowercase<Left>
                                ? [Res, T]
                                : Split<Rest, `${Res}${Left}`>
                                : [Res, T]
type IsOver<T extends string, Flag extends boolean = Uppercase<T> extends Lowercase<T> ? true : false> = T extends `${infer Left}${infer Rest}`
                              ? Uppercase<Left> extends Lowercase<Left>
                                ? Flag extends true
                                  ? IsOver<Rest, Flag>
                                  : false
                                : Flag extends false
                                ? IsOver<Rest, Flag>
                                : false
                              : true
type MyCapitalize<S extends string, Flag extends boolean> = Flag extends true ? Capitalize<Lowercase<S>> : Lowercase<S>
type CamelCase<T extends string, Flag extends boolean = false>
= IsOver<T> extends true
  ? MyCapitalize<T, Flag>
  : CalGap<T>[0] extends `${infer Str}_`
  ? `${Str}${MyCapitalize<Split<CalGap<T>[1]>[0], Flag>}${CamelCase<Split<CalGap<T>[1]>[1], true>}`
  : `${CalGap<T>[0]}${Lowercase<Split<CalGap<T>[1]>[0]>}${CamelCase<Split<CalGap<T>[1]>[1], true>}`

Solution by studymachiney #25013

type CamelCase<S extends string, O extends string=''> = S extends `${infer F}${infer R}`
  ? CamelCase<R, CombineStr1<F, O>>
  :MyReplaceAll<CombineStr1<S, O>, '_', ''>

type CombineStr1<S extends string, O extends string> = O extends `${infer _F}_`
  ? `${O}${Uppercase<S>}`
  : `${O}${Lowercase<S>}`

type MyReplaceAll<S extends string, From extends string, To extends string> =
 S extends `${infer Frist}${From}${infer R}`
   ? `${Frist}${To}${MyReplaceAll<R, From, To>}`
   : S

Solution by GDCzhou #24802

type IsAlphabet<T extends string> = Lowercase<T> extends Uppercase<T> ? false : true;

type CamelCase<S extends string> = S extends `_${infer F}${infer R}` ?
  IsAlphabet<F> extends true ? `${Uppercase<F>}${CamelCase<R>}` : `_${CamelCase<`${F}${R}`>}` :
  S extends `${infer F}${infer R}` ? `${Lowercase<F>}${CamelCase<R>}` : ``;

// old way
// type IsAlphabet<T extends string> = Lowercase<T> extends Uppercase<T> ? false : true;

// type CamelCase<S extends string, _Result extends string/*Too Deep Solution*/ = ``> = S extends `${infer F}${infer R}` ?
//   (F extends `_` ?                                      //_...
//     (R extends `${infer RF}${infer RR}` ?               //_xx...
//       (IsAlphabet<RF> extends true ?                    //_ax...
//         CamelCase<RR, `${_Result}${Uppercase<RF>}`> :   //Ax...
//         CamelCase<R, `${_Result}${F}`>                  //_xx...
//       ) :
//       `${_Result}_`) :                                  //_
//     CamelCase<R, `${_Result}${Lowercase<F>}`>) :        //F...
//   _Result;

Solution by E-uler #24687

type CamelCase<
  S extends string, 
  NewWord extends boolean = false, 
  NewString extends string = ''
> = S extends `${infer First}${infer Rest}`
? First extends '_'
  ? CamelCase<Rest, true, `${NewString}`>
  : NewWord extends true 
    ? CamelCase<Rest, false, `${NewString}${Uppercase<First>}`>
    : CamelCase<Rest, false, `${NewString}${Lowercase<First>}`>
: NewString 

Solution by NeylonR #24442

type CamelCase<S extends string, Result extends string = ''> = 
  S extends `${infer P}${infer R}`
    ? '_' extends P
      ? R extends `${infer NextP}${infer NextR}` 
        ? CamelCase<NextR, `${Result}${Uppercase<NextP>}`> 
        : Result
      : CamelCase<R, `${Result}${Lowercase<P>}`>
    : Result

Solution by flavianh #24361

// 你的答案
type CamelCase<S extends string,First extends boolean = true> = S extends `${infer F}_${infer O}`
? `${
    First extends true 
  ? Lowercase<F>
  :F 
  }${CamelCase<Capitalize<Lowercase<O>>,false>}`
: First extends true
? Lowercase<S>
: Capitalize<S>

Solution by walker-hzx #24301

type CamelCase<S extends string, U extends string = '', Upper extends boolean = false> = S extends `${infer L}${infer R}`
? L extends '_'
 ? CamelCase<R, U, true>
 : Upper extends true
  ? CamelCase<R, `${U}${Uppercase<L>}`, false>
  : CamelCase<R, `${U}${Lowercase<L>}`, false>
: U;

Solution by sabercc #23872

// your answers
type CamelCase<S extends string, U extends string = '', Underline = false> = S extends `${infer L}${infer R}`
  ? L extends '_' 
    ? CamelCase<R, U, true> 
    : Underline extends true
      ? CamelCase<R, `${U}${Uppercase<L>}`>
      : CamelCase<R, `${U}${Lowercase<L>}`>
  : U

Solution by snakeUni #23443

// your answers
type CamelCase<S extends string, U extends string = '', Capital = false> = S extends `${infer L}${infer R}`
  ? L extends '_' 
    ? CamelCase<R, U, true> 
    : Capital extends true
      ? CamelCase<R, `${U}${Uppercase<L>}`>
      : CamelCase<R, `${U}${Lowercase<L>}`>
  : U

Solution by aloneWang #23390

type CamelCase<
  S extends string,
  U extends string = "",
  Cap = false
> = S extends `${infer F}${infer R}`
  ? F extends "_"
    ? CamelCase<R, U, true>
    : Cap extends true
    ? CamelCase<R, `${U}${Uppercase<F>}`, false>
    : CamelCase<R, `${U}${Lowercase<F>}`, false>
  : U;

Solution by coderyoo1 #23017

// 你的答案
type CamelCase_<S extends string> = S extends `${infer Suffix}_${infer Rest}` ? `${Suffix}${CamelCase_<Capitalize<Lowercase<Rest>>>}` : S;
type CamelCase<S extends string> = CamelCase_<Lowercase<S>>;

Solution by jxhhdx #22822

// your answers
type SplitWithChar<T extends string, CurrentStr extends string = '', Arr extends string[] = []> =
T extends `${infer L}${infer R}` ? L extends '_' ? SplitWithChar<R, '', [...Arr, CurrentStr]> : SplitWithChar<R, `${CurrentStr}${L}`, Arr> : [...Arr, CurrentStr]

type UppercaseFirst<T extends string> = T extends `${infer L}${infer R}` ? `${Uppercase<L>}${Lowercase<R>}` : never

type FormatArr<T extends string[], U extends string[] = []> = T extends [infer L, ...infer R] ? U['length'] extends 0 ?
  FormatArr<R, [Lowercase<L>]> : FormatArr<R, [...U, UppercaseFirst<L>]> : U

type CamelCase<T extends string> = T extends `${infer _}_${infer __}` ? Join<FormatArr<SplitWithChar<T>>, ''> : Lowercase<T>

Solution by RThong #22807

type CamelCase<T extends string> = T extends `${infer F}${infer R}`
	? F extends ['_'][number] 
		? R extends `${infer F1}${infer R1}`
			? `${F}${Uppercase<F1>}${CamelCase<Lowercase<R1>>}`
			: R
		: `${Lowercase<F>}${CamelCase<Lowercase<R>>}` 
	: T

Solution by TKBnice #22702

type IsLetter<T extends string> = Uppercase<T> extends Lowercase<T> ? false : true

type CamelCase<S extends string, R extends string = ''> =
  S extends `${infer A}${infer Rest}`
    ? A extends '_'
      ? Rest extends `${infer X}${infer Y}`
        ? IsLetter<X> extends true
          ? CamelCase<`${Y}`, `${R}${Uppercase<X>}`>
          : CamelCase<Rest, `${R}${A}`>
        : CamelCase<'', `${R}${A}`>
      : CamelCase<Rest, `${R}${Lowercase<A>}`>
    : R

It also passed through below edge test cases:


type EdgeCases = [
  Expect<Equal<CamelCase<'foo__bar'>, 'foo_Bar'>>,
  Expect<Equal<CamelCase<'foo_$bar'>, 'foo_$bar'>>,
  Expect<Equal<CamelCase<'foo_bar_'>, 'fooBar_'>>,
  Expect<Equal<CamelCase<'foo_bar__'>, 'fooBar__'>>,
  Expect<Equal<CamelCase<'foo_bar_$'>, 'fooBar_$'>>,
]

Solution by drylint #22211

type CamelCase<S extends string> = S extends `${infer F}_${infer M}${infer E}` ? 
`${Lowercase<F>}${Uppercase<M>}${CamelCase<E>}` : Lowercase<S>;

Solution by Karamuto #21949

// 你的答案
type CamelCase<T extends string, S extends string = Lowercase<T>>
= S extends `${infer A}_${infer B}${infer C}`
? CamelCase<'', `${A}${Uppercase<B>}${Lowercase<C>}`>
: S

Solution by goddnsgit #21847

type CamelCase<S extends string> = S extends `${infer Cur}${infer Next}${infer Rest}` ?
    Cur extends '_' ? `${Uppercase<Next>}${CamelCase<Rest>}` : `${Lowercase<Cur>}${CamelCase<`${Next}${Rest}`>}` : Lowercase<S>

Solution by zhuizhui0429 #21845

type CamelCase<S extends string, C extends string = Lowercase<S>> = 
  C extends `${infer F}_${infer R}` ? `${F}${CamelCase<S, Capitalize<R>>}` : C;

Solution by ivbrajkovic #21634

type StringToUnion<S> = S extends `${infer F}${infer R}`
  ? F | StringToUnion<R>
  : S;
type CapitalizeCamelCase<
  S extends string,
  R extends string = ""
> = S extends `${infer A}_${infer B}` ? 
      CapitalizeCamelCase<B,`${R}${Capitalize<A>}`>  :
      `${R}${Capitalize<S>}`

type CamelCase<S extends string> = "_"  extends  StringToUnion<S> ? 
Uncapitalize<CapitalizeCamelCase<Lowercase<S>>>  : Lowercase<S>;

Solution by so11y #21040

type CamelCase<S extends string> = S extends `${infer L}_${infer C}${infer R}` ? `${Lowercase<L>}${Uppercase<C>}${CamelCase<R>}` : Lowercase<S>;

Update:

type CamelCase<S extends string, SL extends String = Lowercase<S>> = SL extends `${infer L}_${infer C}${infer R}` ? `${L}${Uppercase<C>}${CamelCase<'', R>}` : SL;

Solution by mdakram28 #20649