Patrones
¿Cómo convierto { a: string } & { b: number } en { a: string; b: number } para que los tooltips se lean y las comprobaciones de igualdad pasen?
Un mapeo homomórfico recorre cada clave una vez y reconstruye un único objeto. Los modificadores sobreviven; la intersección no.
La receta
type Prettify<T> = { [K in keyof T]: T[K] } type Base = { a: string } type Extra = { b?: number; readonly c: boolean } type Merged = Prettify<Base & Extra>
La compilación compila esto y comprueba cada resultado de abajo.
Cómo funciona
- 01
type Prettify<T> = { [K in keyof T]: T[K] }Parece que no hace nada, y para un objeto llano así es. Ante una intersección recorre la unión de ambos conjuntos de claves y emite un objeto con todas.
Lo que obtienes
Merged→{ a: string; b?: number | undefined; readonly c: boolean; }Prettify<{ a: 1 } & { b: 2 }>→{ a: 1; b: 2; }Un objeto donde había dos. Nada cambió en la asignabilidad — solo la forma, que es lo que compara
Equal.Prettify<{ a: 1 }> extends { a: 1 } ? true : false→true
Dónde falla
Aplana un nivel. Una intersección anidada dentro de una propiedad sigue siendo intersección, y aplicarlo recursivamente expandirá también cada tipo integrado que toque — incluidos Date y Promise, que rara vez es lo que se quería.
Conclusión
Las intersecciones ensamblan un tipo de objeto; un mapeo homomórfico lo remata. Ensamblar sin rematar es la razón más común de que un tipo con buen aspecto falle una comprobación de igualdad.

