Przejdź do treści
webtype.orgwebtype.orgDwanaście zagadnień · 12/12

    ↑↓ ruch · ⏎ otwórz · esc zamknij

    Zagadnienie 12 z 12

    Dokładna równość

    Każdy test na tej stronie sprawdza dokładną tożsamość typów, a nie przypisywalność. Ten wybór sprawia, że odpowiedź może być *użyteczna* i mimo to nie przejść — a zrozumienie tego odróżnia walkę ze sprawdzarką od jej czytania.

    Dlaczego `extends` nie wystarcza

    type Inter = { a: string } & { b: number }
    type Flat = { a: string; b: number }
    
    type OneWay = Inter extends Flat ? true : false   // true
    type Other = Flat extends Inter ? true : false    // true
    // Mutually assignable — yet they are not the same type.

    Wzajemna przypisywalność jest słabsza niż tożsamość. Przecięcie i spłaszczony obiekt przyjmują się nawzajem, ale różnią się strukturalnie — a sprawdzarka oparta na `extends` uznałaby niedokończoną odpowiedź za poprawną.

    Sztuczka z Equal

    type Equal<X, Y> =
      (<T>() => T extends X ? 1 : 2) extends
      (<T>() => T extends Y ? 1 : 2) ? true : false

    Dwa odroczone warunki są wzajemnie przypisywalne tylko wtedy, gdy kompilator rozwiązuje je identycznie — a robi to wyłącznie dla naprawdę identycznych typów. To wewnętrzny szczegół implementacji, a nie udokumentowana funkcja, i najbliższa rzecz do równości typów, jaką TypeScript udostępnia.

    Spłaszczanie przecięcia

    type Prettify<T> = { [K in keyof T]: T[K] } & {}
    
    type Fixed = Prettify<{ a: string } & { b: number }>
    // { a: string; b: number } — now Equal passes

    Mapowanie po zebranych kluczach tworzy świeży typ obiektowy. Końcowe `& {}` zmusza TypeScript do faktycznego wyliczenia mapowania zamiast trzymania go leniwie — dlatego ten idiom wygląda jak literówka, a nią nie jest.

    Najczęstsza błędna odpowiedź

    // Intent: does this tuple contain exactly `true`?
    type Includes<T extends unknown[], U> = U extends T[number] ? true : false
    
    Includes<[boolean], true>   // true — but the tuple holds boolean, not true

    `extends` pyta, czy `true` mieści się w `boolean` — i mieści. Przynależność to nie przypisywalność, a gdy zadanie mówi „dokładnie”, `extends` jest złym narzędziem.

    Ćwiczenie

    Odpowiedz `true` tylko wtedy, gdy obie strony to ten sam typ — przecięcie nie jest płaskim obiektem.

    Spróbuj

    1
    • Flatten<{ a: 1 } & { b: 2 }>
      { a: 1; b: 2 }

    Do zapamiętania

    Przypisywalne to nie równe. Gdy test odrzuca odpowiedź, która wyraźnie działa, winowajcą jest zwykle przecięcie, którego nikt nie spłaszczył.