00112-hard-capitalizewords

Back

type NotEnglistWord<T extends string> = Uppercase<T> extends Lowercase<T> ? true : false
type CapitalizeWords<S extends string, W extends string = ''> = S extends `${infer R}${infer rest}` ? (NotEnglistWord<R> extends true ? `${Capitalize<W>}${R}${CapitalizeWords<rest>}` : CapitalizeWords<rest, `${W}${R}`>) : Capitalize<W>

Solution by ouzexi #34211

// your answers
type IsNotEnglish<T extends string> = Uppercase<T> extends Lowercase<T> ? true : false;
type MyCapitalize<T extends string> = T extends `${infer F}${infer S}` ? `${Uppercase<F>}${S}` : T;
type Split<T extends string, Words extends string = ''> = T extends `${infer First}${infer Rest}` 
  ? IsNotEnglish<First> extends true
    ? [`${MyCapitalize<Words>}${First}`, ...Split<Rest>]
    : Split<`${Rest}`, `${Words}${First}`>
  : [Capitalize<Words>];

type CapitalizeArray<T extends string[]> = T extends [infer F extends string, ...infer Rest extends string[]]
  ? [Capitalize<F>, ...CapitalizeArray<Rest>]
  : [];

type Join<T extends string[]> = T extends [infer F extends string, ...infer Rest extends string[]]
  ? `${F}${Join<Rest>}`
  : ''

type CapitalizeWords<T extends string> = Join<CapitalizeArray<Split<T>>>;

Solution by kakasoo #32976

// your answers
type IsNotEnglish<T extends string> = Uppercase<T> extends Lowercase<T> ? true : false;
type CapitalizeWords<T extends string, Words extends string = ''> = T extends `${infer First}${infer Rest}` 
  ? IsNotEnglish<First> extends true
    ? `${Capitalize<Words>}${First}${CapitalizeWords<`${Rest}`>}`
    : CapitalizeWords<`${Rest}`, `${Words}${First}`>
  : `${Capitalize<Words>}`;

Solution by kakasoo #32975

不知道怎么判断是否是字母,用了最原始的方法,把它们全部列举出来 🤣🤣

type UpperLetter =
  | "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 LowerLetter =
  | "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 CapitalizeWords<
  S extends string,
  Flag extends boolean = true
> = S extends `${infer L}${infer Rest}`
  ? L extends UpperLetter | LowerLetter
    ? Flag extends true
      ? `${Capitalize<L>}${CapitalizeWords<Rest, false>}`
      : `${L}${CapitalizeWords<Rest, false>}`
    : `${L}${CapitalizeWords<Rest, true>}`
  : "";

Solution by Vampirelee #32606

type CapitalizeWords<T extends string> = T extends `${infer Word} ${infer Rest}` ? `${Capitalize<Word>} ${CapitalizeWords<Rest>}` : Capitalize<T>;

Solution by PCOffline #31067

This CapitalizeWords cannot cut words recursively:

/* _____________ Your Code Here _____________ */


type LowercaseEnglishArray = ['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 UppercaseEnglishArray = ['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 LowercaseEnglishUnion = LowercaseEnglishArray[number]
type UppercaseEnglishUnion = UppercaseEnglishArray[number]

type EnglishWord<S extends string> = S extends `${infer C extends LowercaseEnglishUnion | UppercaseEnglishUnion}${infer RestString extends string}`
  ? `${C}${EnglishWord<RestString>}`
  : ''
type CapitalizeWord<S extends string> = S extends `${infer W extends EnglishWord<S>}` | `${infer W extends EnglishWord<S>}${infer Rest extends string}`
  ? W extends `${infer FirstChar extends LowercaseEnglishUnion | UppercaseEnglishUnion}${infer RestChars extends string}`
    ? `${Uppercase<FirstChar>}${RestChars}`
    : ''
  : ''

type Shift<T extends string> = T extends `${infer First}${infer Rest extends string}`
  ? Rest
  : ''
type CapitalizeWords<S extends string> = S extends `${infer W extends EnglishWord<S>}${infer RestString extends string}`
  ? `${CapitalizeWord<W>}${RestString[0]}${CapitalizeWords<Shift<RestString>>}`
  : S extends `${infer W extends EnglishWord<S>}`
    ? `${CapitalizeWord<W>}`
    : CapitalizeWords<Shift<S>>;

/* _____________ Test Cases _____________ */
import type { Equal, Expect } from '@type-challenges/utils'

type cases = [
  Expect<Equal<LowercaseEnglishArray['length'], 26>>,
  Expect<Equal<UppercaseEnglishArray['length'], 26>>,
  Expect<Equal<'f' extends LowercaseEnglishUnion ? true : false, true>>,
  Expect<Equal<Uppercase<'f'>, 'F'>>,
  Expect<Equal<Uppercase<'foo bar'>, 'FOO BAR'>>,
  Expect<Equal<EnglishWord<'foobar'>, 'foobar'>>,
  Expect<Equal<EnglishWord<'foobar hello world'>, 'foobar'>>,
  Expect<Equal<CapitalizeWord<'foobar'>, 'Foobar'>>,
  Expect<Equal<CapitalizeWord<'FOOBAR'>, 'FOOBAR'>>,
  Expect<Equal<CapitalizeWord<'foo bar'>, ''>>,
  Expect<Equal<Shift<''>, ''>>,
  Expect<Equal<Shift<'321'>, '21'>>,
  Expect<Equal<Shift<'abcd'>, 'bcd'>>,
  Expect<Equal<CapitalizeWords<'foobar'>, 'Foobar'>>,
  Expect<Equal<CapitalizeWords<'FOOBAR'>, 'FOOBAR'>>,
  Expect<Equal<CapitalizeWords<'foobar '>, 'Foobar '>>,
  Expect<Equal<CapitalizeWords<'foo bar'>, 'Foo Bar'>>,
  Expect<Equal<CapitalizeWords<'foo bar hello world'>, 'Foo Bar Hello World'>>,
  Expect<Equal<CapitalizeWords<'foo bar.hello,world'>, 'Foo Bar.Hello,World'>>,
  Expect<Equal<CapitalizeWords<'aa!bb@cc#dd$ee%ff^gg&hh*ii(jj)kk_ll+mm{nn}oo|pp🤣qq'>, 'Aa!Bb@Cc#Dd$Ee%Ff^Gg&Hh*Ii(Jj)Kk_Ll+Mm{Nn}Oo|Pp🤣Qq'>>,
  Expect<Equal<CapitalizeWords<''>, ''>>,
]

Solution by KNHui #30994

type CapitalizeWords<T extends string, S extends string = ''> = T extends `${infer W} ${infer O}` ? CapitalizeWords<O, `${S}${Capitalize<W>} `>  : `${S}${Capitalize<T>}`

Solution by HenrryShaw #27754


// 空字符串情况
type Space = "" | " " | "\n" | "\t"
// Head 为虚拟头节点,默认为 ""
// 不仅要判断头节点为空!还要判断下一个节点是否为空
type CapitalizeWords<S extends string, Head extends string = "", W extends string = ""> =
  S extends `${infer L}${infer R}` ? Head extends Space ? L extends Space ?
  CapitalizeWords<Lowercase<R>, L, `${W}`> :
  CapitalizeWords<Lowercase<R>, L, `${W}${Uppercase<L>}`> : CapitalizeWords<Lowercase<R>, L, `${W}${L}`> : W

Solution by wuxin0011 #27563

// 思路:将遍历的字母存到W中,直到遇到非字母时,取出W进行Capitalize,再清空W再进行搜集处理
type CapitalizeWords<
  S extends string,
  W extends string = ''
> = S extends `${infer A}${infer B}`
  ? Uppercase<A> extends Lowercase<A>
    ? `${Capitalize<`${W}${A}`>}${CapitalizeWords<B>}`
    : CapitalizeWords<B, `${W}${A}`>
  : Capitalize<W>

Solution by smileboyi #27495

type CapitalizeWords<
  S extends string,
  W extends string = ''
> = S extends `${infer A}${infer B}`
  ? Uppercase<A> extends Lowercase<A>
    ? `${Capitalize<`${W}${A}`>}${CapitalizeWords<B>}`
    : CapitalizeWords<B, `${W}${A}`>
  : Capitalize<W>

Solution by smileboyi #27457

type IsLetter<T extends string> = Uppercase<T> extends Lowercase<T>
  ? false
  : true; // check that is difference between uppercase and lowercase

type CapitalizeWords<S extends string, PrevLetter extends string = ' '> = [
  S,
] extends [`${infer CurrentLetter}${infer Tail}`]
  ? IsLetter<PrevLetter> extends false
    ? `${Capitalize<CurrentLetter>}${CapitalizeWords<Tail, CurrentLetter>}`
    : `${CurrentLetter}${CapitalizeWords<Tail, CurrentLetter>}`
  : '';

Solution by jakubjereczek #26659

type CapitalizeWords<
  S extends string,
  Word extends string = '',
  Words extends string = ''
> = S extends `${infer F}${infer R}`
  ? Uppercase<F> extends Lowercase<F>
    ? CapitalizeWords<R, '', `${Words}${Word}${F}`>
    : Word extends ''
    ? CapitalizeWords<R, `${Word}${Uppercase<F>}`, Words>
    : CapitalizeWords<R, `${Word}${F}`, Words>
  : `${Words}${Word}`;

Solution by JohnLi1999 #25241

// your answers
type CapitalizeWords<S extends string, W extends string = ''> = S extends `${infer Left}${infer Rest}`
                                                                ? Uppercase<Left> extends Lowercase<Left>
                                                                ? `${Capitalize<W>}${Left}${CapitalizeWords<Rest>}`
                                                                : CapitalizeWords<Rest, `${W}${Left}`>
                                                                : Capitalize<W>

Solution by studymachiney #24965

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

type CapitalizeWord<W extends string> = 
    W extends `${infer CW}${infer CR}` ? 
      CW extends Uppercase<CW> ? W
      : `${Uppercase<CW>}${CR}`
    : W
;

type CapitalizeWords<S extends string, Result extends string = ''> =
  S extends `${infer C}${infer R}` ?
    isAlphabet<C> extends false ? 
      R extends `${infer CW}${infer CR}` ?
        isAlphabet<CW> extends true ? CapitalizeWords<CR, `${Result}${C}${Uppercase<CW>}`>
        : CapitalizeWords<R, `${Result}${C}`>
      : CapitalizeWord<Result>
    : CapitalizeWords<R, `${Result}${C}`>
  :  CapitalizeWord<Result>
;

Solution by MrNinso #24936

type Whitespace = ' '| ',' | '.'

type CapitalizeWords<S extends string, O extends string = ''> = S extends `${infer F}${infer Rest}`
  ? CapitalizeWords<Rest, CombineStr<F, O>>
  : MyCapitalize<CombineStr<S, O>>

type CombineStr<S extends string, O extends string> = O extends `${infer _F}${Whitespace}` ? `${O}${Uppercase<S>}`: `${O}${S}`

type MyCapitalize<S extends string> = S extends `${infer F}${infer Rest}`
  ? `${Uppercase<F>}${Rest}`
  : S

Solution by GDCzhou #24800

type IsAlphabet<T extends string> = Lowercase<T> extends Uppercase<T> ? false : true;
type GetUpper<T extends string, IsFirst extends boolean> = IsFirst | IsAlphabet<T> extends true ? Uppercase<T> : T;
type GetIsFirst<Pre extends string> = IsAlphabet<Pre> extends true ? false : true;

//平铺式
type CapitalizeWords<S extends string, _IsFirst extends boolean = true> = S extends `${infer F}${infer Sec/*Too Deep Solution*/}${infer R}` ?
  (`${GetUpper<F, _IsFirst>}${GetUpper<Sec, GetIsFirst<F>>}${CapitalizeWords<R, GetIsFirst<Sec>>}`) :
  GetUpper<S, _IsFirst>;

//暂存式
// type CapitalizeWords<S extends string, _IsFirst extends boolean = true, _Result extends string/*Too Deep Solution*/ = ``> = S extends `${infer F}${infer R}` ?
//   (CapitalizeWords<R, GetIsFirst<F>, `${_Result}${GetUpper<F, _IsFirst>}`>) :
//   _Result;

Solution by E-uler #24686

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

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

Solution by NeylonR #24418

// Using a Result variable to hold the result as the type instantiation would be too deep otherwise
type CapitalizeWords<S extends string, PartOfWord = false, Result extends string = ''> = 
S extends `${infer Pre}${infer Rest}`
  ?
  Pre extends Uppercase<Pre> ? CapitalizeWords<Rest, false, `${Result}${Uppercase<Pre>}`>
  : PartOfWord extends true ? CapitalizeWords<Rest, true, `${Result}${Pre}`> :
  CapitalizeWords<Rest, true, `${Result}${Uppercase<Pre>}`>
  : Result

Solution by flavianh #24359

// 你的答案
// 判断分隔符
type IsDelimiter<S extends string> = Lowercase<S> extends 
'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' 
? false : true ;

/**
 * @param {string }R 上次计算的结果 用来解决防止递归次数过大
 */
type CapitalizeWords<S extends string,Delimiter extends string = '.',R extends string = ''> = S extends `${infer F extends string}${infer O extends string}` 
? IsDelimiter<Delimiter>  extends true
  ? CapitalizeWords<O,F,`${R}${Capitalize<F>}`>
  :CapitalizeWords<O,F,`${R}${F}`>
:R;

Solution by walker-hzx #24300

type isLetter<T extends string> = Uppercase<T> extends Lowercase<T> ? false : true;
type CapitalizeWords<S extends string, Exc extends boolean = true, R extends string = ''> = S extends `${infer F}${infer O}`
? isLetter<F> extends true
  ? Exc extends true
    ? CapitalizeWords<O, false, `${R}${Uppercase<F>}`>
    : CapitalizeWords<O, false, `${R}${F}`>
  : CapitalizeWords<O, true, `${R}${F}`>
: R;

Solution by sabercc #23871

// your answers 参考楼下
type NotLetter<T extends string> = Uppercase<T> extends Lowercase<T> ? true : false;

type CapitalizeWords<
  S extends string,
  U extends string = "",
  Cap = true
> = S extends `${infer F}${infer R}`
  ? Cap extends true
    ? CapitalizeWords<R, `${U}${Capitalize<F>}`, NotLetter<F>>
    : CapitalizeWords<R, `${U}${F}`, NotLetter<F>>
  : U;

Solution by snakeUni #23442

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

type CapitalizeWords<
  S extends string,
  U extends string = "",
  Cap = true
> = S extends `${infer F}${infer R}`
  ? Cap extends true
    ? CapitalizeWords<R, `${U}${Capitalize<F>}`, NotLetter<F>>
    : CapitalizeWords<R, `${U}${F}`, NotLetter<F>>
  : U;

Solution by coderyoo1 #23015

// 你的答案
type IsLetter<T extends string> = Uppercase<T> extends Lowercase<T> ? true : false;
type CapitalizeWords_<
  S extends string, 
  R extends string = ""
> = S extends `${infer First}${infer Rest}`
      ? IsLetter<First> extends true
        ? `${Capitalize<`${R}${First}`>}${CapitalizeWords_<Rest>}`
        : CapitalizeWords_<Rest, `${R}${First}`>
      : Capitalize<R>  
type CapitalizeWords<S extends string> = Capitalize<CapitalizeWords_<S>>

Solution by jxhhdx #22821

type CapitalizeWords<T extends string, B extends boolean = false> = 
T extends `${infer F}${infer R}`
? F extends ' ' | '.' |','
  ? R extends `${infer F1}${infer R1}` ? `${F}${Uppercase<F1>}${CapitalizeWords<R1,true>}` : R 
  : `${B extends false ? Uppercase<F> : F}${CapitalizeWords<R,true>}` 
: T

Solution by TKBnice #22695

type IsNotLetter<S extends string> = Uppercase<S> extends Lowercase<S> ? true : false;
type CapitalizeWords_<S extends string, R extends string = ""> = S extends `${infer First}${infer Rest}`
                                           ? IsNotLetter<First> extends true
                                             ? `${Capitalize<`${R}${First}`>}${CapitalizeWords_<Rest>}`
                                             : CapitalizeWords_<Rest, `${R}${First}`>
                                           : Capitalize<R>  
type CapitalizeWords<S extends string> = Capitalize<CapitalizeWords_<S>>

Solution by kfess #22245

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

type CapitalizeWords<S extends string, R extends string = '', Temp extends string = ''> =
  S extends `${infer A}${infer Rest}`
    ? IsLetter<A> extends true
      ? CapitalizeWords<Rest, R, `${Temp}${A}`>
      : CapitalizeWords<Rest, `${R}${Capitalize<Temp>}${A}`>
    : `${R}${Capitalize<Temp>}`

Solution by drylint #22199

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

type CapitalizeWords<S extends string, Trans extends boolean = true, R extends string = ''> = S extends `${infer First}${infer Rest}` 
? IsZimu<First> extends true
  ? Trans extends true 
    ? CapitalizeWords<Rest, false, `${R}${Uppercase<First>}`> 
    : CapitalizeWords<Rest, false, `${R}${First}`>   
  : CapitalizeWords<Rest, true, `${R}${First}`>
: R

Solution by 437204933 #22045

type CapitalizeWord<S extends string> = S extends `${infer Start}${infer Rest}` ? `${Uppercase<Start>}${Rest}` : S;
type CapitalizeWords<S extends string, C extends string=''> = S extends `${infer First}${infer Rest}` ? Lowercase<First> extends Uppercase<First> ?
 `${CapitalizeWord<C>}${First}${CapitalizeWords<Rest>}` : CapitalizeWords<Rest, `${C}${First}`> : CapitalizeWord<C>;

Solution by Karamuto #21948

type Alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
type SplitStr<S extends string, C extends string[] = []> = S extends `${infer F}${infer R}` ? SplitStr<R, [...C, F]> : C;
type AppendStr<T extends string, U extends string> = `${T}${U}`;
type IsAlphabet<T extends string> = T extends SplitStr<Alphabet>[number] ? true : false;
type And<T extends boolean, U extends boolean> = T extends true ? U extends true ? true : false : false;
type Not<T extends boolean> = T extends true ? false : true;

type CapitalizeWords<
  S extends string, 
  C extends string = "", 
  PrevIsNotAlphabet extends boolean = true
> =
  S extends `${infer Curr}${infer Rest}`
    ? CapitalizeWords<
        Rest,
        And<PrevIsNotAlphabet, IsAlphabet<Curr>> extends true
          ? AppendStr<C, Capitalize<Curr>>
          : AppendStr<C, Curr>,
        Not<IsAlphabet<Curr>>
      >
    : C;

Solution by ivbrajkovic #21631

// 不使用 Res 存储去直接拼接,会导致长字符串 deep and possibly infinite error
type CapitalizeWords<S extends string, Prev extends string='',Res extends string = ''> = S extends `${infer L}${infer R}`
  ? Uppercase<Prev> extends Lowercase<Prev>
    ? CapitalizeWords<R,L,`${Res}${Uppercase<L>}`>
    : CapitalizeWords<R,L,`${Res}${L}`>
  : Res

Solution by mo-bai #21173