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

    ↑↓ mover · ⏎ abrir · esc cerrar

    Concepto 12 de 12

    Igualdad exacta

    Cada comprobación de este sitio prueba identidad exacta de tipos y no asignabilidad. Esa elección es la razón de que una respuesta pueda ser *usable* y aun así fallar, y entenderlo marca la diferencia entre pelearse con el verificador y saber leerlo.

    Por qué `extends` no basta

    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.

    La asignabilidad mutua es más débil que la identidad. Una intersección y el objeto aplanado se aceptan mutuamente, pero son estructuralmente distintos, y un verificador basado en `extends` daría por buena una respuesta a medias.

    El truco de Equal

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

    Dos condicionales diferidos solo son asignables entre sí cuando el compilador los resuelve de forma idéntica — algo que solo ocurre con tipos realmente idénticos. Es un detalle interno de implementación, no una función documentada, y es lo más parecido a la igualdad de tipos que expone TypeScript.

    Aplanar una intersección

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

    Mapear sobre las claves acumuladas produce un tipo objeto nuevo. El `& {}` final es lo que obliga a TypeScript a evaluar de verdad el mapeo en vez de mantenerlo perezoso, y por eso el modismo parece una errata y no lo es.

    El error más común

    // 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` pregunta si `true` cabe en `boolean`, y cabe. La pertenencia no es asignabilidad, y cuando un problema dice «exactamente», `extends` es el instrumento equivocado.

    Ejercicio

    Responde `true` solo cuando ambos lados son el mismo tipo — una intersección no es un objeto plano.

    Pruébalo

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

    Para recordar

    Asignable no es igual. Cuando una comprobación rechaza una respuesta que claramente funciona, el culpable suele ser una intersección que nunca se aplanó.