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

    ↑↓ ruch · ⏎ otwórz · esc zamknij

    Zagadnienie 7 z 12

    infer

    `infer` to dopasowanie wzorca. Opisujesz oczekiwany kształt, wstawiasz `infer X` tam, gdzie siedzi interesujący fragment, a kompilator rozwiązuje `X`. Większość pomocników wyciągających z biblioteki standardowej to jeden warunek z jednym `infer` we właściwym miejscu.

    Działa wszędzie, gdzie może pojawić się typ

    type Unwrap<T> = T extends Promise<infer Inner> ? Inner : T
    type Element<T> = T extends (infer E)[] ? E : never
    type Returns<T> = T extends (...a: never[]) => infer R ? R : never
    type Head<T> = T extends [infer H, ...unknown[]] ? H : never
    type Rest<S> = S extends `${string}-${infer R}` ? R : never

    Obietnice, tablice, zwracane typy funkcji, pozycje w krotce, wzorce łańcuchów — mechanizm jest za każdym razem ten sam. Zmienia się tylko otaczający kształt — dlatego nauka jednego uczy wszystkich.

    Ograniczanie tego, co zostaje związane

    // Without the constraint, F is unknown and cannot be
    // interpolated into a template literal.
    type First<T> = T extends [infer F extends string, ...unknown[]]
      ? `${F}!`
      : never

    `infer` może nieść własną klauzulę `extends`, która zawęża wiązanie i pozwala użyć wyniku tam, gdzie wymagany jest konkretny rodzaj typu. Bez niej często dostajesz `unknown`, a błąd pojawia się linijkę po przyczynie.

    Najczęstsza błędna odpowiedź

    // Intent: get the return type of any function.
    type Returns<T> = T extends () => infer R ? R : never
    
    Returns<() => string>          // string
    Returns<(a: number) => string> // never — pattern demands zero parameters
    
    // Fixed: never[] in parameter position accepts any signature,
    // because parameters are checked contravariantly.
    type Returns2<T> = T extends (...a: never[]) => infer R ? R : never

    Wzorzec musi być tak pobłażliwy jak wejścia, które chcesz dopasować. Typ funkcji bez parametrów pasuje tylko do funkcji bez parametrów, więc wszystko inne po cichu wpada w gałąź fałszywą.

    Ćwiczenie

    Wyciągnij typ elementu z typu tablicy.

    Spróbuj

    2
    • ElementOf<string[]>
      string
    • ElementOf<number>
      never

    Do zapamiętania

    Opisz kształt, zaznacz dziurę przez `infer` i pozwól kompilatorowi ją wypełnić. Jeśli nic nie pasuje, to wzorzec jest surowszy niż wejście — nie odwrotnie.

    Ćwiczone w