Przejdź do treści
webtype.org#223 type-level-subtract · par 5

Nr 223 · 31 lipca 2026 · Bezlitosna

Odejmowanie na poziomie typów

Zaimplementuj `Subtract<A, B>` zwracający `A − B` jako literał liczbowy. Gdy `B` jest większe od `A`, odpowiedzią jest `never` — nie ma ujemnych długości krotek.

01

Spróbuj rozwiązać samodzielnie

Par 5

Zagadka

type-level-subtract.ts
type BuildTuple<N extends number, Acc extends unknown[] = []> =
  Acc['length'] extends N ? Acc : BuildTuple<N, [...Acc, unknown]>
Podejście 1 z 5Jeszcze nie sprawdzone

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

Testy

4
  • Subtract<5, 3>
    2
  • Subtract<3, 3>
    0
  • Subtract<10, 4>
    6
  • Subtract<2, 5>
    never

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ć.

Archiwum
02

Rozwiązanie z komentarzem

Opublikowano 1 sierpnia 2026

Rozwiązanie

type Subtract<A extends number, B extends number> =
  BuildTuple<A> extends [...BuildTuple<B>, ...infer Rest] ? Rest['length'] : never

Najczęstsza błędna odpowiedź

type Subtract<A extends number, B extends number> =
  [...BuildTuple<A>, ...BuildTuple<B>]['length']

To dodawanie pod inną nazwą. Złączenie dwóch krotek może je tylko wydłużyć; odejmowanie musi krotkę *rozłożyć*, czyli wymaga dopasowania wzorca, a nie budowania.

Linia po linii

  1. [...BuildTuple<B>, ...infer Rest]

    Wzorzec ustala przedrostek dokładnie `B` elementów, a `Rest` pochłania resztę. Dopasowanie udaje się tylko wtedy, gdy obiekt jest co najmniej tak długi.

  2. : never

    Gdy `B > A`, przedrostka nie da się dopasować, warunek zawodzi i wypada `never` — uczciwa odpowiedź dla odejmowania, którego ta arytmetyka nie potrafi wyrazić.

Do zapamiętania

Budowanie krotek dodaje; ich rozkładanie odejmuje. Każda operacja arytmetyczna, jaką TypeScript potrafi na typach, to jeden z tych dwóch ruchów w przebraniu.