yunliuyan / type-challenges

typescript-challenges
0 stars 2 forks source link

00020-medium-kebabcase #20

Open yunliuyan opened 1 year ago

yunliuyan commented 1 year ago

KebabCase medium #template-literal

by Johnson Chu @johnsoncodehk

Take the Challenge    日本語 한국어

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"

Back Share your Solutions Check out Solutions

Related Challenges

114・CamelCase
yunliuyan commented 1 year ago

思路

检测是否是大写字母,如果是,用小写替换,非第一个元素前面加上'-'。infer大法好。

代码实现

type letters = {
  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 KebabCase<S extends string, isFirst = true> = S extends '' ? '' : S extends `${infer L}${infer R}` ? L extends keyof letters ? `${isFirst extends true ? '' : '-'}${letters[L]}${KebabCase<R, false>}` : `${L}${KebabCase<R, false>}` : never

type FooBarBaz = KebabCase<"FooBarBaz">
const foobarbaz: FooBarBaz = "foo-bar-baz"

type DoNothing = KebabCase<"do-nothing">
const doNothing: DoNothing = "do-nothing"
Janice-Fan commented 1 year ago
// Uncapitalize用于将字符串的第一个字符转换为小写。
type KebabCase<T extends string> = T extends `${infer T1}${infer T2}` 
  ? Uncapitalize<T2> extends T2 
  ? `${Uncapitalize<T1>}${KebabCase<T2>}` 
  : `${Uncapitalize<T1>}-${KebabCase<T2>}` 
  : T;

type FooBarBaz = KebabCase<"FooBarBaz">
const foobarbaz: FooBarBaz = "foo-bar-baz"

type DoNothing = KebabCase<"do-nothing">
const doNothing: DoNothing = "do-nothing"
liangchengv commented 1 year ago
type KebabCase<S extends string> = S extends `${infer First}${infer Rest}` ? Rest extends Uncapitalize<Rest> ? `${Uncapitalize<First>}${KebabCase<Rest>}` : `${Uncapitalize<First>}-${KebabCase<Rest>}` : S;

type FooBarBaz = KebabCase<"FooBarBaz">
const foobarbaz: FooBarBaz = "foo-bar-baz"

type DoNothing = KebabCase<"do-nothing">
const doNothing: DoNothing = "do-nothing"