Saltar al contenido
webtype.orgwebtype.orgDoce conceptos · 7/12

    ↑↓ mover · ⏎ abrir · esc cerrar

    Concepto 7 de 12

    infer

    `infer` es emparejamiento de patrones. Describes la forma que esperas, pones `infer X` donde está la parte interesante, y el compilador resuelve `X`. Casi todos los helpers de extracción de la librería estándar son un condicional con un `infer` bien colocado.

    Funciona en cualquier sitio donde quepa un tipo

    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

    Promesas, arrays, retornos de función, posiciones de tupla, patrones de cadena — el mecanismo es idéntico cada vez. Solo cambia la forma que lo rodea, y por eso aprender uno te enseña todos.

    Restringir lo que se liga

    // 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

    Un `infer` puede llevar su propia cláusula `extends`, que acota lo que liga y permite usar el resultado donde se exige un tipo concreto. Sin ella sueles obtener `unknown`, y el error aparece una línea después de la causa.

    El error más común

    // 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

    El patrón debe ser tan permisivo como las entradas que quieras emparejar. Un tipo de función sin parámetros solo encaja con funciones sin parámetros, así que todo lo demás cae en silencio en la rama falsa.

    Ejercicio

    Extrae el tipo de elemento de un tipo de array.

    Pruébalo

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

    Para recordar

    Describe la forma, marca el hueco con `infer` y deja que el compilador lo rellene. Si nada encaja, el patrón es más estricto que la entrada — no al revés.

    Se practica en