解决两个问题:
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