跳到主要内容

Kebabcase

介绍

替换camelCasePascalCase字符串为kebab-case. FooBarBaz -> foo-bar-baz

ts
type FooBarBaz = KebabCase<"FooBarBaz">
const foobarbaz: FooBarBaz = "foo-bar-baz"
type DoNothing = KebabCase<"do-nothing">
const doNothing: DoNothing = "do-nothing"
ts
type FooBarBaz = KebabCase<"FooBarBaz">
const foobarbaz: FooBarBaz = "foo-bar-baz"
type DoNothing = KebabCase<"do-nothing">
const doNothing: DoNothing = "do-nothing"
View on GitHub

起点

ts
/* _____________ Your Code Here _____________ */
 
type KebabCase<S> = any
 
/* _____________ Test Cases _____________ */
 
 
type cases = [
Expect<Equal<KebabCase<'FooBarBaz'>, 'foo-bar-baz'>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<KebabCase<'fooBarBaz'>, 'foo-bar-baz'>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<KebabCase<'foo-bar'>, 'foo-bar'>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<KebabCase<'foo_bar'>, 'foo_bar'>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<KebabCase<'Foo-Bar'>, 'foo--bar'>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<KebabCase<'ABC'>, 'a-b-c'>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<KebabCase<'-'>, '-'>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<KebabCase<''>, ''>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<KebabCase<'😎'>, '😎'>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
]
 
ts
/* _____________ Your Code Here _____________ */
 
type KebabCase<S> = any
 
/* _____________ Test Cases _____________ */
 
 
type cases = [
Expect<Equal<KebabCase<'FooBarBaz'>, 'foo-bar-baz'>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<KebabCase<'fooBarBaz'>, 'foo-bar-baz'>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<KebabCase<'foo-bar'>, 'foo-bar'>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<KebabCase<'foo_bar'>, 'foo_bar'>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<KebabCase<'Foo-Bar'>, 'foo--bar'>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<KebabCase<'ABC'>, 'a-b-c'>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<KebabCase<'-'>, '-'>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<KebabCase<''>, ''>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<KebabCase<'😎'>, '😎'>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
]
 
take the challenge

解决方案

Spoiler warning // Click to reveal answer
ts
// most popular
 
 
type KebabCase<S extends string> = S extends `${infer S1}${infer S2}`
? S2 extends Uncapitalize<S2>
? `${Uncapitalize<S1>}${KebabCase<S2>}`
: `${Uncapitalize<S1>}-${KebabCase<S2>}`
: S;
 
ts
// most popular
 
 
type KebabCase<S extends string> = S extends `${infer S1}${infer S2}`
? S2 extends Uncapitalize<S2>
? `${Uncapitalize<S1>}${KebabCase<S2>}`
: `${Uncapitalize<S1>}-${KebabCase<S2>}`
: S;
 
ts
// 方法2 when i see my solution, i am tired too.
type StrToArr<T extends string ,U extends any[] = []> = T extends `${infer F}${infer Rest}`
? StrToArr<Rest, [...U, F]>
: U;
 
type ArrToStr<T extends any[], U extends string = ''> = T extends [infer F, ...infer Rest]
? ArrToStr<Rest, `${U}${F}`>
Type 'F' is not assignable to type 'string | number | bigint | boolean | null | undefined'.2322Type 'F' is not assignable to type 'string | number | bigint | boolean | null | undefined'.
: U;
 
type UpperToLower = {
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 strArr<S extends string> = StrToArr<S>;
 
type FormatArr<strArr, T extends any[] = []> = strArr extends [infer F, ...infer Rest extends string[]]
? [F extends keyof UpperToLower ? `-${UpperToLower[F]}` : F, ...FormatArr<Rest>]
: T;
 
type KebabCase<S extends string> = ArrToStr<FormatArr<strArr<S>>> extends `-${infer Rest extends string}`
? Rest extends '' ? '-' : Rest
: ArrToStr<FormatArr<strArr<S>>>
 
 
ts
// 方法2 when i see my solution, i am tired too.
type StrToArr<T extends string ,U extends any[] = []> = T extends `${infer F}${infer Rest}`
? StrToArr<Rest, [...U, F]>
: U;
 
type ArrToStr<T extends any[], U extends string = ''> = T extends [infer F, ...infer Rest]
? ArrToStr<Rest, `${U}${F}`>
Type 'F' is not assignable to type 'string | number | bigint | boolean | null | undefined'.2322Type 'F' is not assignable to type 'string | number | bigint | boolean | null | undefined'.
: U;
 
type UpperToLower = {
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 strArr<S extends string> = StrToArr<S>;
 
type FormatArr<strArr, T extends any[] = []> = strArr extends [infer F, ...infer Rest extends string[]]
? [F extends keyof UpperToLower ? `-${UpperToLower[F]}` : F, ...FormatArr<Rest>]
: T;
 
type KebabCase<S extends string> = ArrToStr<FormatArr<strArr<S>>> extends `-${infer Rest extends string}`
? Rest extends '' ? '-' : Rest
: ArrToStr<FormatArr<strArr<S>>>
 
 
view more solutions