00612-medium-kebabcase

Back

解决两个问题:
1. 如何判断是否为大写字母
T extends Uppercase<T> 为true 同时 T extends Lowercase<T> 为false,则该字母为大写字母
2. 是否为首字母
默认为true,其他传值为false


// 判断是否为大写字母
type isUpperLetter<T extends string> = T extends Uppercase<T> 
? T extends Lowercase<T>
  ? false
  : true
: false;

type KebabCase<S, IsFirst = true> = S extends `${infer L}${infer R}` 
? `${isUpperLetter<L> extends true ? IsFirst extends true ? '' : '-' : ''}${Lowercase<L>}${KebabCase<R, false>}`
: S;

Solution by chenghao125 #33432

// 判断是否为大写字母
type isUpperLetter<T extends string> = T extends Uppercase<T> 
? T extends Lowercase<T>
  ? false
  : true
: false;

type KebabCase<S, IsFirst = true> = S extends `${infer L}${infer R}` 
? `${isUpperLetter<L> extends true ? IsFirst extends true ? '' : '-' : ''}${Lowercase<L>}${KebabCase<R, false>}`
: S;

Solution by chenghao125 #33431

// your answers
type KebabCase<S> = S extends `${infer R}${infer T}`
  ? `${Uncapitalize<R>}${T extends Uncapitalize<T> ? "" : "-"}${KebabCase<T>}`
  : S

The KebabCase type recursively breaks down a string into its first character and the rest, converting the first character to lowercase and adding a hyphen before any uppercase letters in the rest of the string. This process continues until the entire string is transformed into kebab-case

Solution by lezhu1234 #33284

interface Hi{ 'A':'a'; 'B':'b'; 'F':'f'; }

type KebabCaseMy<T extends string, D extends string =''> = D extends '' ? T extends ${infer C extends keyof Hi}${infer R} ? KebabCaseMy<R,${D}${Hi[C]}> : T extends ${infer C}${infer R} ? KebabCaseMy<R,${D}${C}> :D :T extends ${infer C extends keyof Hi}${infer R} ? KebabCaseMy<R,${D}-${Hi[C]}> : T extends ${infer C}${infer R} ? KebabCaseMy<R,${D}${C}> : D;

Solution by Shlufman #33083

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

type KebabCase<S extends string, Acc extends string = ''> = S extends `${infer F}${infer R}`
  ? R extends UnCapitalize<R>
    ? KebabCase<R, `${Acc}${F}`>
    : `${UnCapitalize<`${Acc}${F}`>}-${KebabCase<R>}`
  : UnCapitalize<Acc>

Solution by rimo030 #32980


type UpperMap = {
  'A': 'a'
  'B': 'b'
  'C': 'c'
  'D': 'd'
  'E': 'e'
  'F': 'f'
  'G': 'g'
  'H': 'h'
  'I': 'i'
  'J': 'j'
  'K': 'k'
  'L': 'l'
  'M': 'm'
  'N': 'n'
  'O': 'o'
  'P': 'p'
  'Q': 'q'
  'R': 'r'
  'S': 's'
  'T': 't'
  'U': 'u'
  'V': 'v'
  'W': 'w'
  'X': 'x'
  'Y': 'y'
  'Z': 'z'
}

type Upper = keyof UpperMap

type Step1<S extends string> = S extends `${infer Cap}${infer Rest}` ? Cap extends Upper ? `${UpperMap[Cap]}${Rest}` : S : S

type Step2<S extends string, A extends string = ''> = S extends `${infer Cap}${infer Rest}` ? Cap extends Upper ? Step2<Rest, `${A}-${UpperMap[Cap]}`> : Step2<Rest, `${A}${Cap}`> : A

type KebabCase<S extends string> = Step2<Step1<S>>

Solution by ZJia1231 #32489

type KebabCase<S extends string> = 
  S extends `${infer First}${infer Rest}` 
    ?  Rest extends Uncapitalize<Rest>
      ? `${Uncapitalize<First>}${KebabCase<Rest>}`
      : `${Uncapitalize<First>}-${KebabCase<Rest>}`
    : S

재귀적 사고, Uncapitalize 유틸리티 타입

Solution by dev-hobin #32417

// your answers
type KebabCase<S extends string> = S extends `${infer L}${infer R}`
? R extends Uncapitalize<R>
  ? `${Uncapitalize<L>}${KebabCase<R>}`
  : `${Uncapitalize<L>}-${KebabCase<R>}`
  : S;

Solution by pea-sys #32355

type KebabCase<S extends string, U extends string = S> = U extends `${infer F}${infer L}`
	? L extends ""
		? F extends ToUpperCase
			? S extends `${infer F1}${F}`
				? F1 extends ""
					? `${LowerCase[F]}`
					: `${F1}-${LowerCase[F]}`
				: never
			: S
		: F extends ToUpperCase
		? KebabCase<
				S extends `${infer F2}${F}${infer L1}`
					? F2 extends ""
						? `${LowerCase[F]}${L1}`
						: `${F2}-${LowerCase[F]}${L1}`
					: S,
				L
		  >
		: KebabCase<S, L>
	: "";

interface LowerCase {
	A: "a";
	B: "b";
	C: "c";
	D: "d";
	E: "e";
	F: "f";
	G: "g";
	H: "h";
	I: "i";
	J: "j";
	K: "k";
	L: "l";
	M: "m";
	N: "n";
	O: "o";
	P: "p";
	Q: "q";
	R: "r";
	S: "s";
	T: "t";
	U: "u";
	V: "v";
	W: "w";
	X: "x";
	Y: "y";
	Z: "z";
}

type ToUpperCase = keyof LowerCase;

Solution by gasmg #32002

type KebabCase<S> = S extends `${infer S1}${infer S2}`
  ? S2 extends Uncapitalize<S2>
    ? `${Uncapitalize<S1>}${KebabCase<S2>}`
    : `${Uncapitalize<S1>}-${KebabCase<S2>}`
  : S;

Solution by jinyoung234 #31937

type KebabCase<S> = S extends `${infer S1}${infer S2}` 
  ? S2 extends Uncapitalize<S2> ? `${Uncapitalize<S1>}${KebabCase<Uncapitalize<S2>>}` : `${Uncapitalize<S1>}-${KebabCase<Uncapitalize<S2>>}`
  : S;

Solution by kai-phan #31657

type KebabCase<S extends string> = S extends `${infer S1}${infer S2}`
  ? S2 extends Uncapitalize<S2>
  ? `${Uncapitalize<S1>}${KebabCase<S2>}`
  : `${Uncapitalize<S1>}-${KebabCase<S2>}`
  : S;

Solution by vipulpathak113 #31515

type KebabCase<S extends string> = S extends `${infer S1}${infer S2}`
  ? S2 extends Uncapitalize<S2>
  ? `${Uncapitalize<S1>}${KebabCase<S2>}`
  : `${Uncapitalize<S1>}-${KebabCase<S2>}`
  : S;

Solution by MyeonghoonNam #31440

type KebabCase<S extends string, P extends string = ''> = 
  S extends `${infer A}${infer Rest}`
    ? Lowercase<A> extends Uppercase<A>
      ? `${A}${KebabCase<Rest, '-'>}`
      : `${A extends Uppercase<A> ? `${P}${Lowercase<A>}` : A}${KebabCase<Rest, '-'>}`
  : S;

Solution by ricky-fn #31337

type Uppers = {
  F:'f',
  B:'b',
  C:'c',
  A:'a',
  //...
}
type KebabCase<S extends string, Tmp extends string = ""> = S extends `${infer A}${infer B}` ? KebabCase<B, `${Tmp}${A extends keyof Uppers ? `${Tmp extends '' ? '':'-'}${Uppers[A]}` : A}`> : Tmp;

Solution by eward957 #31251

// your answers

type KebabCase<S> = S extends `${infer First}${infer Rest}`
  ? Rest extends Uncapitalize<Rest>
    ? `${Lowercase<First>}${KebabCase<Rest>}`
    : `${Lowercase<First>}-${KebabCase<Rest>}`
  : S;

Solution by d1zzzzy #31230

// your answers
type KebabCase<S extends string,  Pre extends string = ''> = S extends `${infer L}${infer Rest}` ? (
  L extends Lowercase<L> ? KebabCase<Rest, `${Pre}${L}`> : (
    (Pre extends '' ? KebabCase<Rest, `${Lowercase<L>}`> 
    : KebabCase<Rest, `${Pre}-${Lowercase<L>}`>)
  )
): Pre;

Solution by CDSP98 #31031

type KebabCase<S, P = S> = S extends `${infer C}${infer R}`
  ? IsUppercase<C> extends true
    ? `${C}${R}` extends `${infer ST}` // is uppercase letters
      ? `${ST extends P /* is first letters */ ? '' : '-'}${Lowercase<C>}${KebabCase<R, P>}`
      : never
    : `${C}${KebabCase<R, P>}`
  : S // single letters

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

Solution by Chan-Yuxi #30558

type KebabCase<S extends string, R extends string = ''> = S extends '' 
  ? R
  : S extends `${infer F}${infer Rest}` 
    ? KebabCase<Rest, `${R}${F extends Uppercase<F> ? (Lowercase<F> extends F ? '' : R extends '' ? '' : '-') : ''}${Lowercase<F>}`>
    : R;

Solution by kai-phan #30378

type KebabCase<S extends string> =
  S extends `${infer L}${infer R}`
    ? R extends '' | `${Lowercase<string>}${string}`
      ? `${Lowercase<L>}${KebabCase<R>}`
      : `${Lowercase<L>}-${KebabCase<R>}`
    : ''

or

type KebabCase<S extends string> =
  S extends `${infer L}${infer R}`
    ? R extends Uncapitalize<R>
      ? `${Uncapitalize<L>}${KebabCase<R>}`
      : `${Uncapitalize<L>}-${KebabCase<R>}`
    : ''

Solution by sbr61 #29972

type KebabCase<S extends string, T = Uncapitalize<S>> = T extends `${infer R}${infer P}`
    ? P extends Uncapitalize<P>
        ? `${R}${KebabCase<P>}`
        : `${R}-${KebabCase<P>}`
    : T

Solution by lovezhangchuangxin #29962

type KebabCaseChild<Str extends string> =
  Str extends `${infer First}${infer Rest}`
  ? First extends Lowercase<First>
  ? `${First}${KebabCaseChild<Rest>}`
  : `-${Lowercase<First>}${KebabCaseChild<Rest>}`
  : Str;

type KebabCase<Str extends string> = Str extends '-' ? '-' : KebabCaseChild<Str> extends `-${infer V}` ? V : KebabCaseChild<Str>

Solution by tclxshunquan-wang #29915

type KebabCase<S, T extends string = ""> =
  S extends `${infer First}${infer Rest}` ?
    First extends '' ?
      T :
      First extends Lowercase<First> ?
        KebabCase<Rest, `${T}${First}`> :
        T extends "" ?
          KebabCase<Rest, `${Lowercase<First>}`> :
          KebabCase<Rest, `${T}-${Lowercase<First>}`> :
  T;  

Solution by maximallain #29697

type KebabCase<S> = S extends `${infer L}${infer R}`
  ? R extends Uncapitalize<R>
    ? `${Uncapitalize<L>}${KebabCase<R>}`
    : `${Uncapitalize<L>}-${KebabCase<R>}`
  : S;

Solution by flt3150sk #29513

type StringToUnion<S extends string> = S extends `${infer First}${infer Rest}`
  ? StringToUnion<Rest> | First 
  : never
type CapitalLetters = StringToUnion<"ABCDEFGHIJKLMNOPQRSTUVWXYZ">
type KebabCase<S extends string, Seperator extends string = ""> = S extends `${infer First}${infer Rest}`
  ? First extends CapitalLetters
  ? `${Seperator}${Lowercase<First>}${KebabCase<Rest, "-">}`
  : `${Lowercase<First>}${KebabCase<Rest, "-">}`
  : ""

Solution by MohammadArasteh #29506

type ToLowerCase = {
    A: 'a',
    B: 'b',
    C: 'c',
    D: 'd',
    E: 'e',
    F: 'f',
    G: 'g',
    H: 'h',
    I: 'i',
    J: 'j',
    K: 'k',
    L: 'l',
    M: 'm',
    N: 'n',
    O: 'o',
    P: 'p',
    Q: 'q',
    R: 'r',
    S: 's',
    T: 't',
    U: 'u',
    V: 'v',
    W: 'w',
    X: 'x',
    Y: 'y',
    Z: 'z'
}

type UpperCase = keyof ToLowerCase;

type KebabCase<T extends string, S = false> = T extends `${infer E}${infer R}` ?
    E extends UpperCase ?
        S extends false ?
            `${ToLowerCase[E]}${KebabCase<R, true>}` :
            `-${ToLowerCase[E]}${KebabCase<R, true>}` :
        `${E}${KebabCase<R, true>}` : T;

type FooBarBaz = KebabCase<'FooBarBaz'>;

Solution by sundial-dreams #29458

  type IsUpper<S extends string> = S extends Lowercase<S> ? false : true;
type Inner<S extends string> = S extends `${infer F}${infer O}`
  ? IsUpper<F> extends true
  ? `-${Lowercase<F>}${Inner<O>}`
  : `${F}${Inner<O>}`
  : S;

type KebabCase<S extends string> = S extends `${infer F}${infer O}`
  ? `${Lowercase<F>}${Inner<O>}`
  : S;

Solution by sabercc #29339

type String2Union<S extends string> = S extends `${infer First}${ infer Rest }` ? First | String2Union<Rest> : never
type Upper2Lower<S extends string> = S extends Capitalize<String2Union<'abcdefghijklmnopqrstuvwxyz'>> ? `-${ Lowercase<S> }` : S
type RemoveFirstConnection<S extends string, RemoveConnection extends boolean> = RemoveConnection extends true ? S extends `-${ infer Rest }` ? Rest : S : S
type KebabCase<S extends string, RemoveConnection extends boolean = true> = S extends '-' ? S : S extends `${infer First}${ infer Rest }` ? RemoveFirstConnection<`${ Upper2Lower<First> }${ KebabCase<Rest, false> }`, RemoveConnection> : S

Solution by Yirujet #29303

// 여기 풀이를 입력하세요
type KebabCase<S extends string> = S extends `${infer First}${infer Rest}` ? Rest extends Uncapitalize<Rest> ? `${Uncapitalize<First>}${KebabCase<Rest>}` : `${Uncapitalize<First>}-${KebabCase<Rest>}` : S;

Solution by eodnjs467 #29207

// your answers
 /***
* F - ooBar
* if ooBar === Uncapitalize<ooBar>
*    Uncapitalize<F> + KebabCase<ooBar>
* 
* and so on 
* 
* 
  *  */  
type KebabCase<S> = S extends `${infer T}${infer R}` ?   
                          R extends Uncapitalize<R> ? 
                              `${Uncapitalize<T>}${KebabCase<R>}` 
                            : `${Uncapitalize<T>}-${KebabCase<R>}` 
                          : S

Solution by kerolossamir165 #29103