type-challenges:KebabCase

55 阅读1分钟

KebabCase

问题描述

Replace the camelCase or PascalCase string with kebab-case.

FooBarBaz -> foo-bar-baz

For example

type FooBarBaz = KebabCase<"FooBarBaz">
const foobarbaz: FooBarBaz = "foo-bar-baz"type DoNothing = KebabCase<"do-nothing">
const doNothing: DoNothing = "do-nothing"
// ============= Test Cases =============
import type { Equal, Expect } from './test-utils'type cases = [
  Expect<Equal<KebabCase<'FooBarBaz'>, 'foo-bar-baz'>>,
  Expect<Equal<KebabCase<'fooBarBaz'>, 'foo-bar-baz'>>,
  Expect<Equal<KebabCase<'foo-bar'>, 'foo-bar'>>,
  Expect<Equal<KebabCase<'foo_bar'>, 'foo_bar'>>,
  Expect<Equal<KebabCase<'Foo-Bar'>, 'foo--bar'>>,
  Expect<Equal<KebabCase<'ABC'>, 'a-b-c'>>,
  Expect<Equal<KebabCase<'-'>, '-'>>,
  Expect<Equal<KebabCase<''>, ''>>,
  Expect<Equal<KebabCase<'😎'>, '😎'>>,
]
​
​
// ============= Your Code Here =============
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'
// 答案1
type KebabCase<S extends string, U = S> = S extends `${infer R}${infer P}`
  ? R extends UpperLetter
    ? U extends `${infer _}${infer US}`
      ? P extends US
        ? `${Lowercase<R>}${KebabCase<P, S>}`
        : `-${Lowercase<R>}${KebabCase<P, S>}`
      : S
    : `${R}${KebabCase<P, S>}`
  : S
​
// 答案2
type KebabCase<S extends string> = S extends `${infer F}${infer R}`
  ? R extends Uncapitalize<R>
  ? `${Uncapitalize<F>}${KebabCase<R>}`
  : `${Uncapitalize<F>}-${KebabCase<R>}`
  : S;
​
​

Uncapitalize 内置类型,用来将字符串的第一个字符转为小写。