Skip to content
webtype.orgwebtype.org#267 kebab-case · par 4

    ↑↓ move · ⏎ open · esc close

    No. 267 · September 19, 2026 · Hard

    Kebab case

    Implement `KebabCase<S>` so a camel- or Pascal-cased string becomes lowercase words joined by hyphens.

    01

    Try the puzzle yourself

    Par 4

    Puzzle

    kebab-case.ts
    Stroke 1 of 4Not run yet

    Replace ??? — your solution is checked against the cases below. Tab indents; press Escape then Tab to move focus out.

    Checks

    3
    • KebabCase<'FooBar'>
      'foo-bar'
    • KebabCase<'alreadyKebab'>
      'already-kebab'
    • KebabCase<'plain'>
      'plain'

    How a check is judged Exact type equality, not assignability — an intersection is not the same as the flattened object.

    How everyone did

    Fewer than 5 people have solved this one so far. The distribution appears once there is enough of a sample to mean anything.

    Short game

    Fewest characters

    No public scores yet.

    Archive
    02

    Annotated solution

    Published September 20, 2026

    The solution

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

    The common wrong answer

    type KebabCase<S extends string> = Lowercase<S>

    `Lowercase` changes letters but forgets where the word boundaries were. Once every capital is gone there is no information left from which to insert the hyphens.

    Line by line

    1. R extends Uncapitalize<R>

      The suffix begins lowercase when uncapitalizing it changes nothing. If it changes, its first character marks a new word.

    Takeaway

    Case conversion must detect boundaries before normalising case; transformation destroys the evidence you need for parsing.

    Uses