Przejdź do treści
webtype.orgwebtype.org

    ↑↓ ruch · ⏎ otwórz · esc zamknij

    Nr 253 · 5 września 2026 · Trudna

    Snake case

    Zaimplementuj SnakeCase<S>, aby "helloWorld" stawało się "hello_world". Za wielkie litery liczą się tylko litery — cyfry i symbole mają przechodzić nietknięte.

    01

    Spróbuj rozwiązać samodzielnie

    Par 4

    Zagadka

    snake-case.ts
    Podejście 1 z 4Jeszcze nie sprawdzone

    Zastąp ??? — rozwiązanie sprawdzamy przypadkami poniżej. Tab wcina; naciśnij Escape, a potem Tab, by wyjść fokusem.

    Testy

    4
    • SnakeCase<'helloWorld'>—
      → 'hello_world'
    • SnakeCase<'a1B'>—
      → 'a1_b'
    • SnakeCase<'foo'>—
      → 'foo'
    • SnakeCase<''>—
      → ''

    Jak oceniamy test Dokładna równość typów, nie przypisywalność — przecięcie to nie to samo co spłaszczony obiekt.

    Jak poszło innym

    Tę zagadkę rozwiązało jak dotąd mniej niż 5 osób. Rozkład pojawi się, gdy próbka będzie na tyle duża, by coś znaczyć.

    Gra na krótkim dystansie

    Najmniej znaków

    Nie ma jeszcze publicznych wyników.

    Archiwum
    02

    Rozwiązanie z komentarzem

    Opublikowano 6 września 2026

    Rozwiązanie

    type SnakeCase<S extends string> =
      S extends `${infer H}${infer R}`
        ? H extends Uppercase<H>
          ? H extends Lowercase<H>
            ? `${H}${SnakeCase<R>}`
            : `_${Lowercase<H>}${SnakeCase<R>}`
          : `${H}${SnakeCase<R>}`
        : S

    Najczęstsza błędna odpowiedź

    type SnakeCase<S extends string> =
      S extends `${infer H}${infer R}`
        ? H extends Uppercase<H>
          ? `_${Lowercase<H>}${SnakeCase<R>}`
          : `${H}${SnakeCase<R>}`
        : S

    "1" extends Uppercase<"1"> jest prawdą, bo Uppercase zostawia wszystko, co nie jest małą literą, dokładnie takim, jakie zastało. Każda cyfra, spacja i symbol traktowane są więc jak wielka litera i dostają własne podkreślenie: "a1B" wychodzi jako "a_1_b". Wielkość znaku to nie jeden test, lecz dwa — równy swojej wersji wielkiej *i* różny od swojej małej.

    Linia po linii

    1. `${infer H}${infer R}`

      Dwa symbole zastępcze bez niczego pomiędzy odcinają dokładnie jeden znak. To typowy odpowiednik przechodzenia po tekście indeks po indeksie.

    2. H extends Lowercase<H> ? ... : ...

      Drugi test wyklucza znaki niebędące literami. Cyfra jest równa i swojej wersji wielkiej, i małej, więc trafia do gałęzi, która przepuszcza ją bez zmian.

    3. : S

      Pusty ciąg nie pasuje do żadnego jednoznakowego wzorca, więc spada do przypadku bazowego i zwraca sam siebie — co zarazem zatrzymuje rekurencję.

    Do zapamiętania

    Uppercase i Lowercase są funkcjami totalnymi: nigdy nie zawodzą, po prostu nic nie robią znakom bez wielkości. Każdy test oparty tylko na jednej z nich po cichu źle sklasyfikuje każdą napotkaną cyfrę i symbol.

    Wykorzystuje