<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Programación · DacaCode &lt;/&gt;</title><link>https://blog.dacadev.com/categories/programaci%C3%B3n/</link><description>Blog de tecnología, programación y electrónica, para compartir conocimientos, experiencias y tutoriales con este apasionante mundo.</description><generator>Hugo</generator><language>es-CO</language><copyright>Copyright © 2026 DacaDev. All rights reserved.</copyright><lastBuildDate>Tue, 07 Jul 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.dacadev.com/categories/programaci%C3%B3n/index.xml" rel="self" type="application/rss+xml"/><image><url>https://blog.dacadev.com/images/blog-logo.png</url><title>DacaCode &lt;/&gt;</title><link>https://blog.dacadev.com/</link></image><item><title>Patrones de Diseño: Factory</title><link>https://blog.dacadev.com/programacion/patrones-de-diseno/fabrica/</link><pubDate>Tue, 07 Jul 2026 00:00:00 +0000</pubDate><guid>https://blog.dacadev.com/programacion/patrones-de-diseno/fabrica/</guid><dc:creator>Dacadev</dc:creator><category>programación</category><description>Aprende los patrones de fabricación (Simple, Factory Method y Abstract Factory) en Python y cómo se relacionan con el principio de inversión de dependencias.</description><media:content url="https://blog.dacadev.com/images/programming/design-patterns/factory/banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#simple-factory"&gt;Simple Factory&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#factory-method"&gt;Factory Method&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#abstract-factory"&gt;Abstract Factory&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#factory-method-vs-abstract-factory"&gt;Factory Method vs Abstract Factory&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#static-factory"&gt;Static Factory&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#principio-de-inversión-de-dependencias"&gt;Principio de Inversión de Dependencias&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#consideraciones"&gt;Consideraciones&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#continúa-la-serie"&gt;Continúa la serie&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;p&gt;La instanciación directa de clases concretas es uno de los puntos más costosos de acoplamiento en un diseño orientado a objetos. Cada &lt;code&gt;new&lt;/code&gt; o llamada explícita a un constructor ata al cliente a una implementación específica, dificultando la extensión y la sustitución de componentes. Los &lt;strong&gt;patrones factory&lt;/strong&gt; encapsulan esa decisión en un lugar controlado, permitiendo evolucionar la creación de objetos sin propagar cambios a todo el código consumidor.&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;🚀 Los patrones &lt;strong&gt;factory&lt;/strong&gt; encapsulan la creación de objetos y desacoplan al cliente de las clases concretas que necesita instanciar.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Este artículo forma parte de la serie de &lt;a href="https://blog.dacadev.com/programacion/patrones-de-diseno/que-son"



 


&gt;patrones de diseño&lt;/a&gt;. Analizaremos tres variantes de fabricación (&lt;strong&gt;Simple Factory&lt;/strong&gt;, &lt;strong&gt;Factory Method&lt;/strong&gt; y &lt;strong&gt;Abstract Factory&lt;/strong&gt;), su relación con el &lt;strong&gt;Principio de Inversión de Dependencias&lt;/strong&gt; y los trade-offs que conviene considerar al elegir uno u otro.&lt;/p&gt;
&lt;h2 id="simple-factory"&gt;Simple Factory&lt;/h2&gt;
&lt;p&gt;El &lt;strong&gt;Simple Factory&lt;/strong&gt; no es un patrón de diseño formal del catálogo GoF, sino un idiom recurrente: encapsular la lógica de creación de objetos dentro de un método (usualmente estático) que decide qué instancia devolver en función de un parámetro. Es un buen punto de partida para entender los patrones que veremos a continuación.&lt;/p&gt;




 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;&lt;strong&gt;GoF&lt;/strong&gt; significa &lt;strong&gt;&amp;ldquo;Gang of Four&amp;rdquo;&lt;/strong&gt; (la &amp;ldquo;Banda de los Cuatro&amp;rdquo;): los cuatro autores del libro &lt;em&gt;Design Patterns&lt;/em&gt; (1994) que catalogó los 23 patrones de diseño clásicos. Cuando decimos que un patrón &amp;ldquo;es GoF&amp;rdquo;, significa que aparece en ese catálogo original.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Supongamos una pizzería que produce distintos tipos de pizzas. Sin un factory, el cliente tendría que conocer todas las clases concretas y decidir cuál instanciar. Con un &lt;code&gt;SimpleFactory&lt;/code&gt; esa decisión queda centralizada:&lt;/p&gt;
&lt;pre class="mermaid"&gt;classDiagram
 class PizzaStore {
 -factory: SimplePizzaFactory
 +order_pizza(kind) Pizza
 }
 class SimplePizzaFactory {
 +create_pizza(kind) Pizza
 }
 class Pizza {
 &amp;lt;&amp;lt;abstract&amp;gt;&amp;gt;
 +prepare()
 +bake()
 +box()
 }
 class CheesePizza
 class VeggiePizza
 class PepperoniPizza

 PizzaStore --&amp;gt; SimplePizzaFactory : usa
 SimplePizzaFactory ..&amp;gt; Pizza : crea
 Pizza &amp;lt;|-- CheesePizza
 Pizza &amp;lt;|-- VeggiePizza
 Pizza &amp;lt;|-- PepperoniPizza
&lt;/pre&gt;

&lt;p&gt;Implementación mínima en Python:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#e06c75"&gt;abc&lt;/span&gt; &lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ABC&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;abstractmethod&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;Pizza&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;ABC&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#61afef"&gt;@abstractmethod&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;prepare&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;: &lt;span style="color:#56b6c2"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;bake&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;Horneando la pizza&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;box&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;Empacando la pizza&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;CheesePizza&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;Pizza&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;prepare&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;Preparando pizza de queso&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;VeggiePizza&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;Pizza&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;prepare&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;Preparando pizza vegetariana&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;SimplePizzaFactory&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;create_pizza&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;kind&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;str&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Pizza&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;if&lt;/span&gt; &lt;span style="color:#e06c75"&gt;kind&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;==&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;cheese&amp;#34;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CheesePizza&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;if&lt;/span&gt; &lt;span style="color:#e06c75"&gt;kind&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;==&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;veggie&amp;#34;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;VeggiePizza&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;raise&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ValueError&lt;/span&gt;(&lt;span style="color:#98c379"&gt;f&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#34;Tipo de pizza no soportado: &lt;/span&gt;&lt;span style="color:#98c379"&gt;{&lt;/span&gt;&lt;span style="color:#e06c75"&gt;kind&lt;/span&gt;&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;PizzaStore&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#56b6c2;font-weight:bold"&gt;__init__&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;factory&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;SimplePizzaFactory&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;factory&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;factory&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;order_pizza&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;kind&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;str&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Pizza&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;pizza&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;factory&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;create_pizza&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;kind&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;pizza&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;prepare&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;pizza&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;bake&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;pizza&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;box&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;pizza&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El cliente (&lt;code&gt;PizzaStore&lt;/code&gt;) ya no depende de las clases concretas; toda la lógica de selección vive en el factory. La limitación es evidente: si necesitamos que distintas sucursales produzcan variantes propias de cada pizza, el &lt;code&gt;if/elif&lt;/code&gt; termina explotando. Ese es exactamente el problema que resuelve &lt;strong&gt;Factory Method&lt;/strong&gt;.&lt;/p&gt;




 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;El Simple Factory es útil como técnica de refactor cuando queremos aislar una serie de condicionales de creación, pero &lt;strong&gt;no&lt;/strong&gt; ofrece extensibilidad vía herencia.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="factory-method"&gt;Factory Method&lt;/h2&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;El &lt;strong&gt;Factory Method&lt;/strong&gt; define una interfaz para crear un objeto, pero delega en las subclases la decisión de qué clase concreta instanciar.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;En lugar de tener una única clase factory que decide con condicionales, el &lt;strong&gt;Factory Method&lt;/strong&gt; define un método abstracto de creación en la superclase. Cada subclase implementa ese método y devuelve el producto concreto que corresponda. La instanciación se &lt;strong&gt;difiere&lt;/strong&gt; a las subclases.&lt;/p&gt;
&lt;pre class="mermaid"&gt;classDiagram
 class Creator {
 &amp;lt;&amp;lt;abstract&amp;gt;&amp;gt;
 +factory_method() Product
 +operation()
 }
 class ConcreteCreatorA {
 +factory_method() Product
 }
 class ConcreteCreatorB {
 +factory_method() Product
 }
 class Product {
 &amp;lt;&amp;lt;abstract&amp;gt;&amp;gt;
 }
 class ConcreteProductA
 class ConcreteProductB

 Creator &amp;lt;|-- ConcreteCreatorA
 Creator &amp;lt;|-- ConcreteCreatorB
 Product &amp;lt;|-- ConcreteProductA
 Product &amp;lt;|-- ConcreteProductB
 ConcreteCreatorA ..&amp;gt; ConcreteProductA : crea
 ConcreteCreatorB ..&amp;gt; ConcreteProductB : crea
&lt;/pre&gt;

&lt;p&gt;Consideremos un ejemplo canónico: una jerarquía de animales donde cada subclase decide qué instancia producir. La superclase define el flujo (&lt;code&gt;show_animal&lt;/code&gt;) que consume el producto creado por el &lt;code&gt;factory_method&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#e06c75"&gt;abc&lt;/span&gt; &lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ABC&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;abstractmethod&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;Animal&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;ABC&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#61afef"&gt;@abstractmethod&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;make_sound&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;str&lt;/span&gt;: &lt;span style="color:#56b6c2"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#61afef"&gt;@abstractmethod&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;create_animal&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;Animal&amp;#34;&lt;/span&gt;: &lt;span style="color:#56b6c2"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;show_animal&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;animal&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;create_animal&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;f&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#34;El animal dice: &lt;/span&gt;&lt;span style="color:#98c379"&gt;{&lt;/span&gt;&lt;span style="color:#e06c75"&gt;animal&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;make_sound&lt;/span&gt;()&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;Dog&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;Animal&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;make_sound&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;str&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;Guau!&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;create_animal&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Animal&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Dog&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;Cat&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;Animal&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;make_sound&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;str&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;Miau!&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;create_animal&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Animal&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Cat&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;Dog&lt;/span&gt;()&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;show_animal&lt;/span&gt;() &lt;span style="color:#7f848e"&gt;# El animal dice: Guau!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;Cat&lt;/span&gt;()&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;show_animal&lt;/span&gt;() &lt;span style="color:#7f848e"&gt;# El animal dice: Miau!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El punto clave es que &lt;code&gt;Animal.show_animal&lt;/code&gt; es &lt;strong&gt;agnóstico&lt;/strong&gt; a la clase concreta: opera sobre la abstracción &lt;code&gt;Animal&lt;/code&gt; y delega la instanciación a &lt;code&gt;create_animal&lt;/code&gt;. Añadir un nuevo animal implica una nueva subclase, no modificar código existente — cumpliendo el principio abierto/cerrado.&lt;/p&gt;




 
 





 


&lt;div class="notice tip"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z" /&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Tip&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Factory Method depende de &lt;strong&gt;herencia&lt;/strong&gt;: cada subclase implementa el método de creación. Es ideal cuando la variación entre productos está atada a la variación de la clase creadora.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="abstract-factory"&gt;Abstract Factory&lt;/h2&gt;
&lt;p&gt;Mientras Factory Method crea &lt;strong&gt;un&lt;/strong&gt; producto, el &lt;strong&gt;Abstract Factory&lt;/strong&gt; crea &lt;strong&gt;familias completas&lt;/strong&gt; de productos relacionados sin acoplar al cliente a las clases concretas de cada familia.&lt;/p&gt;
&lt;p&gt;Un caso clásico: una aplicación que renderiza componentes de UI para distintos sistemas operativos. Botones y checkboxes de Windows deben usarse juntos, igual que los de macOS; mezclarlos rompe la coherencia visual. El Abstract Factory garantiza que solo se combinen componentes de la misma familia.&lt;/p&gt;
&lt;pre class="mermaid"&gt;classDiagram
 class GUIFactory {
 &amp;lt;&amp;lt;abstract&amp;gt;&amp;gt;
 +create_button() Button
 +create_checkbox() Checkbox
 }
 class WindowsFactory
 class MacFactory
 class Button {
 &amp;lt;&amp;lt;abstract&amp;gt;&amp;gt;
 +render()
 }
 class Checkbox {
 &amp;lt;&amp;lt;abstract&amp;gt;&amp;gt;
 +render()
 }
 class WindowsButton
 class WindowsCheckbox
 class MacButton
 class MacCheckbox

 GUIFactory &amp;lt;|-- WindowsFactory
 GUIFactory &amp;lt;|-- MacFactory
 Button &amp;lt;|-- WindowsButton
 Button &amp;lt;|-- MacButton
 Checkbox &amp;lt;|-- WindowsCheckbox
 Checkbox &amp;lt;|-- MacCheckbox
 WindowsFactory ..&amp;gt; WindowsButton : crea
 WindowsFactory ..&amp;gt; WindowsCheckbox : crea
 MacFactory ..&amp;gt; MacButton : crea
 MacFactory ..&amp;gt; MacCheckbox : crea
&lt;/pre&gt;

&lt;p&gt;Implementación en Python:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#e06c75"&gt;abc&lt;/span&gt; &lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ABC&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;abstractmethod&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;Button&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;ABC&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#61afef"&gt;@abstractmethod&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;render&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;: &lt;span style="color:#56b6c2"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;Checkbox&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;ABC&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#61afef"&gt;@abstractmethod&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;render&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;: &lt;span style="color:#56b6c2"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;WindowsButton&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;Button&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;render&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;Renderizando botón de Windows&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;WindowsCheckbox&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;Checkbox&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;render&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;Renderizando checkbox de Windows&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;MacButton&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;Button&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;render&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;Renderizando botón de macOS&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;MacCheckbox&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;Checkbox&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;render&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;Renderizando checkbox de macOS&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;GUIFactory&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;ABC&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#61afef"&gt;@abstractmethod&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;create_button&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Button&lt;/span&gt;: &lt;span style="color:#56b6c2"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#61afef"&gt;@abstractmethod&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;create_checkbox&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Checkbox&lt;/span&gt;: &lt;span style="color:#56b6c2"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;WindowsFactory&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;GUIFactory&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;create_button&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Button&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;WindowsButton&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;create_checkbox&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Checkbox&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;WindowsCheckbox&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;MacFactory&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;GUIFactory&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;create_button&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Button&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;MacButton&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;create_checkbox&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Checkbox&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;MacCheckbox&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;Application&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#56b6c2;font-weight:bold"&gt;__init__&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;factory&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;GUIFactory&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;factory&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;factory&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;create_ui&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;button&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;factory&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;create_button&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;checkbox&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;factory&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;create_checkbox&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;button&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;render&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;checkbox&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;render&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;factory&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;GUIFactory&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;WindowsFactory&lt;/span&gt;() &lt;span style="color:#7f848e"&gt;# o MacFactory()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;Application&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;factory&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;create_ui&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;Application&lt;/code&gt; depende exclusivamente de &lt;code&gt;GUIFactory&lt;/code&gt;, &lt;code&gt;Button&lt;/code&gt; y &lt;code&gt;Checkbox&lt;/code&gt; — todas abstracciones. Cambiar de familia consiste en inyectar una factory distinta; el resto del código permanece intacto.&lt;/p&gt;
&lt;h3 id="factory-method-vs-abstract-factory"&gt;Factory Method vs Abstract Factory&lt;/h3&gt;
&lt;p&gt;Aunque comparten espíritu, no son intercambiables:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Factory Method&lt;/strong&gt; usa &lt;strong&gt;herencia&lt;/strong&gt;: la subclase decide qué producto crear implementando un método.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Abstract Factory&lt;/strong&gt; usa &lt;strong&gt;composición&lt;/strong&gt;: el cliente recibe una factory y llama a varios métodos de creación sobre ella, obteniendo una familia de productos coherentes.&lt;/li&gt;
&lt;li&gt;Factory Method escala en la dimensión de &amp;ldquo;un producto que varía&amp;rdquo;; Abstract Factory escala en la dimensión de &amp;ldquo;múltiples productos que varían de forma correlacionada&amp;rdquo;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="static-factory"&gt;Static Factory&lt;/h2&gt;
&lt;p&gt;El &lt;strong&gt;Static Factory&lt;/strong&gt; es una variante ligera que expone métodos de clase estáticos para construir instancias, en lugar de exponer constructores públicos. Es común en librerías del ecosistema Java y en APIs de Python que ofrecen métodos como &lt;code&gt;datetime.now()&lt;/code&gt; o &lt;code&gt;Path.home()&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;Connection&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#56b6c2;font-weight:bold"&gt;__init__&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;dsn&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;str&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;_dsn&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;dsn&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#61afef"&gt;@classmethod&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;from_env&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;cls&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;Connection&amp;#34;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;os&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;cls&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;dsn&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;&lt;span style="color:#e06c75"&gt;os&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;environ&lt;/span&gt;[&lt;span style="color:#98c379"&gt;&amp;#34;DATABASE_URL&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#61afef"&gt;@classmethod&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;in_memory&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;cls&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;Connection&amp;#34;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;cls&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;dsn&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#34;sqlite://:memory:&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ventajas: los métodos estáticos pueden tener nombres semánticos (&lt;code&gt;from_env&lt;/code&gt;, &lt;code&gt;in_memory&lt;/code&gt;) que documentan la intención mucho mejor que un constructor sobrecargado. Limitación: no permite polimorfismo — no es reemplazable en tiempo de ejecución como sí lo son Factory Method o Abstract Factory.&lt;/p&gt;
&lt;h2 id="principio-de-inversión-de-dependencias"&gt;Principio de Inversión de Dependencias&lt;/h2&gt;
&lt;p&gt;El &lt;strong&gt;Principio de Inversión de Dependencias&lt;/strong&gt; (DIP, la &amp;ldquo;D&amp;rdquo; de SOLID) enuncia dos reglas:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Los módulos de alto nivel no deben depender de módulos de bajo nivel. Ambos deben depender de abstracciones.&lt;/li&gt;
&lt;li&gt;Las abstracciones no deben depender de detalles. Los detalles deben depender de abstracciones.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Los patrones factory son una herramienta natural para aplicar DIP: al centralizar la creación en una abstracción, el módulo de alto nivel deja de instanciar clases concretas. Volviendo al ejemplo de la pizzería:&lt;/p&gt;
&lt;pre class="mermaid"&gt;flowchart LR
 subgraph Antes[&amp;#34;Sin DIP&amp;#34;]
 A1[PizzaStore] --&amp;gt; A2[CheesePizza]
 A1 --&amp;gt; A3[VeggiePizza]
 A1 --&amp;gt; A4[PepperoniPizza]
 end
 subgraph Despues[&amp;#34;Con DIP + Factory&amp;#34;]
 B1[PizzaStore] --&amp;gt; B2[Pizza abstracta]
 B3[CheesePizza] --&amp;gt; B2
 B4[VeggiePizza] --&amp;gt; B2
 B5[PepperoniPizza] --&amp;gt; B2
 end
&lt;/pre&gt;

&lt;p&gt;En &amp;ldquo;Antes&amp;rdquo;, el flujo de dependencia va de alto a bajo nivel: &lt;code&gt;PizzaStore&lt;/code&gt; conoce todas las pizzas concretas. En &amp;ldquo;Después&amp;rdquo;, &lt;strong&gt;ambos&lt;/strong&gt; dependen de la abstracción &lt;code&gt;Pizza&lt;/code&gt;: la dependencia queda &lt;strong&gt;invertida&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Un ejemplo aislado en Python que muestra el patrón:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#e06c75"&gt;abc&lt;/span&gt; &lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ABC&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;abstractmethod&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;MessageSender&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;ABC&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#61afef"&gt;@abstractmethod&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;send&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;message&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;str&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;: &lt;span style="color:#56b6c2"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;EmailSender&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;MessageSender&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;send&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;message&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;str&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;f&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#34;Enviando email: &lt;/span&gt;&lt;span style="color:#98c379"&gt;{&lt;/span&gt;&lt;span style="color:#e06c75"&gt;message&lt;/span&gt;&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;SmsSender&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;MessageSender&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;send&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;message&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;str&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;f&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#34;Enviando SMS: &lt;/span&gt;&lt;span style="color:#98c379"&gt;{&lt;/span&gt;&lt;span style="color:#e06c75"&gt;message&lt;/span&gt;&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;NotificationService&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#56b6c2;font-weight:bold"&gt;__init__&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;sender&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;MessageSender&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;_sender&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sender&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;notify&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;message&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;str&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;_sender&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;send&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;message&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;NotificationService&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;EmailSender&lt;/span&gt;())&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;notify&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;Nuevo despliegue exitoso&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;NotificationService&lt;/code&gt; no conoce &lt;code&gt;EmailSender&lt;/code&gt; ni &lt;code&gt;SmsSender&lt;/code&gt;; solo la abstracción &lt;code&gt;MessageSender&lt;/code&gt;. Un factory puede alimentar esa dependencia según configuración, entorno o feature flags, sin tocar &lt;code&gt;NotificationService&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="consideraciones"&gt;Consideraciones&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Todos los factories encapsulan la creación de objetos y reducen el acoplamiento a implementaciones concretas.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Simple Factory&lt;/strong&gt; no es un patrón GoF; es un idiom útil para aislar condicionales de creación en un único lugar.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Factory Method&lt;/strong&gt; depende de &lt;strong&gt;herencia&lt;/strong&gt;: cada subclase implementa el método de creación y decide el producto concreto.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Abstract Factory&lt;/strong&gt; depende de &lt;strong&gt;composición&lt;/strong&gt;: el cliente recibe una factory y obtiene familias de productos coherentes.&lt;/li&gt;
&lt;li&gt;Los tres refuerzan el &lt;strong&gt;Principio de Inversión de Dependencias&lt;/strong&gt; al hacer que el código cliente dependa de abstracciones, no de tipos concretos.&lt;/li&gt;
&lt;li&gt;El DIP es una guía transversal, no un patrón: aplica siempre que quieras evitar el acoplamiento con implementaciones específicas.&lt;/li&gt;
&lt;li&gt;Factory es una &lt;strong&gt;técnica de diseño&lt;/strong&gt;, no una clase específica. Su nombre puede variar (&lt;code&gt;build&lt;/code&gt;, &lt;code&gt;create&lt;/code&gt;, &lt;code&gt;from_x&lt;/code&gt;), lo importante es la intención: encapsular la construcción de objetos.&lt;/li&gt;
&lt;/ul&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;🚀 Elige &lt;strong&gt;Simple Factory&lt;/strong&gt; para aislar condicionales, &lt;strong&gt;Factory Method&lt;/strong&gt; cuando la variación está atada a la jerarquía del creador, y &lt;strong&gt;Abstract Factory&lt;/strong&gt; cuando necesitas coherencia entre múltiples productos relacionados.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="continúa-la-serie"&gt;Continúa la serie&lt;/h2&gt;
&lt;p&gt;Si te interesa seguir explorando patrones de diseño, revisa los otros artículos de la serie:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blog.dacadev.com/programacion/patrones-de-diseno/que-son"



 


&gt;Qué son los patrones de diseño&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.dacadev.com/programacion/patrones-de-diseno/estrategia"



 


&gt;Patrón Estrategia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.dacadev.com/programacion/patrones-de-diseno/observador"



 


&gt;Patrón Observador&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.dacadev.com/programacion/patrones-de-diseno/decorador"



 


&gt;Patrón Decorador&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>SQL: Transacciones, Índices y Constraints</title><link>https://blog.dacadev.com/programacion/sql/08-transacciones-indices-constraints/</link><pubDate>Fri, 26 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/programacion/sql/08-transacciones-indices-constraints/</guid><dc:creator>Dacadev</dc:creator><category>programación</category><description>Aprende transacciones en SQL con COMMIT, ROLLBACK, índices y constraints para proteger integridad y optimizar consultas.</description><media:content url="https://blog.dacadev.com/images/programming/sql/transactions-constraints/banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#qué-es-una-transacción-en-sql"&gt;Qué es una transacción en SQL&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#candados-y-concurrencia"&gt;Candados y concurrencia&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#iniciar-una-transacción"&gt;Iniciar una transacción&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#terminar-una-transacción"&gt;Terminar una transacción&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#savepoints-dentro-de-una-transacción"&gt;Savepoints dentro de una transacción&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#índices-y-constraints"&gt;Índices y constraints&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#creación-de-índices"&gt;Creación de índices&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#índices-únicos"&gt;Índices únicos&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#índices-multicolumna"&gt;Índices multicolumna&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#tipos-de-índices"&gt;Tipos de índices&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#índices-b-tree"&gt;Índices B-tree&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#índices-bitmap"&gt;Índices bitmap&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#índices-de-texto"&gt;Índices de texto&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#cómo-se-usan-los-índices"&gt;Cómo se usan los índices&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#constraints-restricciones-de-integridad"&gt;Constraints: restricciones de integridad&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#conclusión-de-la-serie-sql"&gt;Conclusión de la serie SQL&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;p&gt;En sistemas con múltiples usuarios escribiendo datos al mismo tiempo, la diferencia entre una aplicación confiable y una que corrompe información suele estar en cómo manejas &lt;strong&gt;transacciones en SQL&lt;/strong&gt;, &lt;strong&gt;índices&lt;/strong&gt; y &lt;strong&gt;constraints&lt;/strong&gt;. En el artículo anterior analizamos &lt;a href="https://blog.dacadev.com/programacion/sql/07-vistas-views"



 


&gt;Vistas (Views)&lt;/a&gt;; ahora cerramos la serie con mecanismos de integridad y rendimiento.&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;En este artículo vas a aprender cómo iniciar y cerrar transacciones con &lt;code&gt;COMMIT&lt;/code&gt; y &lt;code&gt;ROLLBACK&lt;/code&gt;, cuándo usar savepoints, cómo funcionan los índices B-tree, bitmap y full-text, y cómo las constraints mantienen reglas de integridad dentro del esquema.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="qué-es-una-transacción-en-sql"&gt;Qué es una transacción en SQL&lt;/h2&gt;
&lt;p&gt;Una &lt;strong&gt;transacción&lt;/strong&gt; agrupa una o varias sentencias SQL que deben ejecutarse como una unidad lógica. El objetivo es que los cambios se apliquen completos o no se apliquen en absoluto.&lt;/p&gt;
&lt;p&gt;Consideremos una transferencia bancaria. Restar dinero de una cuenta y sumarlo a otra no son acciones independientes desde el punto de vista del negocio. Si una actualización se ejecuta y la otra falla, el sistema queda en un estado inconsistente.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;START&lt;/span&gt; &lt;span style="color:#c678dd"&gt;TRANSACTION&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#7f848e"&gt;/* retirar dinero de la primera cuenta, validando saldo suficiente */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;UPDATE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;account&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SET&lt;/span&gt; &lt;span style="color:#e06c75"&gt;avail_balance&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;avail_balance&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;-&lt;/span&gt; &lt;span style="color:#d19a66"&gt;500&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;account_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;9988&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;AND&lt;/span&gt; &lt;span style="color:#e06c75"&gt;avail_balance&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#d19a66"&gt;500&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;IF&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#e06c75"&gt;exactly&lt;/span&gt; &lt;span style="color:#e06c75"&gt;one&lt;/span&gt; &lt;span style="color:#c678dd"&gt;row&lt;/span&gt; &lt;span style="color:#e06c75"&gt;was&lt;/span&gt; &lt;span style="color:#e06c75"&gt;updated&lt;/span&gt; &lt;span style="color:#c678dd"&gt;by&lt;/span&gt; &lt;span style="color:#e06c75"&gt;the&lt;/span&gt; &lt;span style="color:#e06c75"&gt;previous&lt;/span&gt; &lt;span style="color:#c678dd"&gt;statement&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;THEN&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#7f848e"&gt;/* depositar dinero en la segunda cuenta */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;UPDATE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;account&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SET&lt;/span&gt; &lt;span style="color:#e06c75"&gt;avail_balance&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;avail_balance&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;+&lt;/span&gt; &lt;span style="color:#d19a66"&gt;500&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;account_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;9989&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;IF&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#e06c75"&gt;exactly&lt;/span&gt; &lt;span style="color:#e06c75"&gt;one&lt;/span&gt; &lt;span style="color:#c678dd"&gt;row&lt;/span&gt; &lt;span style="color:#e06c75"&gt;was&lt;/span&gt; &lt;span style="color:#e06c75"&gt;updated&lt;/span&gt; &lt;span style="color:#c678dd"&gt;by&lt;/span&gt; &lt;span style="color:#e06c75"&gt;the&lt;/span&gt; &lt;span style="color:#e06c75"&gt;previous&lt;/span&gt; &lt;span style="color:#c678dd"&gt;statement&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;THEN&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#7f848e"&gt;/* todo funcionó, hacer los cambios permanentes */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;COMMIT&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;ELSE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#7f848e"&gt;/* algo falló, deshacer todos los cambios de esta transacción */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;ROLLBACK&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;END&lt;/span&gt; &lt;span style="color:#c678dd"&gt;IF&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;ELSE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#7f848e"&gt;/* saldo insuficiente o error durante la actualización */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;ROLLBACK&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;END&lt;/span&gt; &lt;span style="color:#c678dd"&gt;IF&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;En este flujo, &lt;code&gt;COMMIT&lt;/code&gt; confirma los cambios y &lt;code&gt;ROLLBACK&lt;/code&gt; revierte todo lo ejecutado desde el inicio de la transacción. La base de datos actúa como una frontera de consistencia.&lt;/p&gt;
&lt;h3 id="candados-y-concurrencia"&gt;Candados y concurrencia&lt;/h3&gt;
&lt;p&gt;Cuando varias sesiones intentan leer o escribir los mismos datos, el motor puede usar &lt;strong&gt;candados&lt;/strong&gt; (&lt;em&gt;locks&lt;/em&gt;) sobre filas, páginas o tablas. Los locks evitan que una transacción lea datos en transición o sobrescriba cambios que todavía no han sido confirmados.&lt;/p&gt;
&lt;h2 id="iniciar-una-transacción"&gt;Iniciar una transacción&lt;/h2&gt;
&lt;p&gt;Los servidores de base de datos suelen manejar la creación de transacciones de una de estas dos formas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Siempre existe una transacción activa asociada a la sesión. Cuando la transacción actual termina, el servidor inicia automáticamente una nueva.&lt;/li&gt;
&lt;li&gt;Cada sentencia SQL se confirma automáticamente, a menos que inicies una transacción explícita.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;En MySQL, una transacción explícita puede comenzar con:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;start&lt;/span&gt; &lt;span style="color:#c678dd"&gt;transaction&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



 
 





 


&lt;div class="notice tip"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z" /&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Tip&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Puedes configurar el comportamiento de &lt;code&gt;autocommit&lt;/code&gt; según el motor y el cliente que uses.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="terminar-una-transacción"&gt;Terminar una transacción&lt;/h2&gt;
&lt;p&gt;Una vez iniciada una transacción, necesitas terminarla explícitamente para que los cambios sean permanentes. &lt;code&gt;COMMIT&lt;/code&gt; marca los cambios como definitivos y libera recursos usados durante la transacción,.&lt;/p&gt;
&lt;p&gt;Si decides deshacer lo ejecutado desde el inicio de la transacción, usas &lt;code&gt;ROLLBACK&lt;/code&gt;. El servidor devuelve los datos al estado previo de la transacción.&lt;/p&gt;
&lt;p&gt;Además de &lt;code&gt;COMMIT&lt;/code&gt; y &lt;code&gt;ROLLBACK&lt;/code&gt;, una transacción puede terminar por otros eventos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;El servidor se apaga; al reiniciar, la transacción pendiente se revierte automáticamente.&lt;/li&gt;
&lt;li&gt;Ejecutas una sentencia de esquema como &lt;code&gt;ALTER TABLE&lt;/code&gt;; en varios motores esto puede confirmar la transacción actual e iniciar otra.&lt;/li&gt;
&lt;li&gt;Ejecutas otro &lt;code&gt;START TRANSACTION&lt;/code&gt;; algunos motores confirman la transacción anterior antes de abrir la nueva.&lt;/li&gt;
&lt;li&gt;El servidor detecta un &lt;strong&gt;deadlock&lt;/strong&gt;, elige una transacción como víctima y la revierte para desbloquear el sistema.&lt;/li&gt;
&lt;/ul&gt;




 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Las sentencias DDL no siempre participan en transacciones igual que las sentencias DML. Antes de mezclar &lt;code&gt;ALTER TABLE&lt;/code&gt;, &lt;code&gt;CREATE INDEX&lt;/code&gt; o cambios de esquema con operaciones de datos, revisa el comportamiento específico de tu motor.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h3 id="savepoints-dentro-de-una-transacción"&gt;Savepoints dentro de una transacción&lt;/h3&gt;
&lt;p&gt;Los &lt;strong&gt;savepoints&lt;/strong&gt; permiten definir puntos intermedios de rollback dentro de una misma transacción. En lugar de revertir todo, puedes regresar a un punto específico y continuar trabajando.&lt;/p&gt;
&lt;h2 id="índices-y-constraints"&gt;Índices y constraints&lt;/h2&gt;
&lt;p&gt;Una consulta sin apoyo puede obligar al servidor a escanear fila por fila. En tablas con millones de registros y decenas de columnas, esto se convierte en un cuello de botella.&lt;/p&gt;
&lt;p&gt;Los &lt;strong&gt;índices&lt;/strong&gt; son estructuras auxiliares que permiten encontrar filas con menos trabajo. Aceleran búsquedas, filtros, joins y ordenamientos.&lt;/p&gt;
&lt;h2 id="creación-de-índices"&gt;Creación de índices&lt;/h2&gt;
&lt;p&gt;Para crear un índice en MySQL podemos usar &lt;code&gt;ALTER TABLE&lt;/code&gt;. Supongamos que el sistema consulta clientes frecuentemente por correo electrónico:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ALTER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;TABLE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ADD&lt;/span&gt; &lt;span style="color:#c678dd"&gt;INDEX&lt;/span&gt; &lt;span style="color:#e06c75"&gt;idx_email&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;email&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;Query&lt;/span&gt; &lt;span style="color:#e06c75"&gt;OK&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;0&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#e06c75"&gt;affected&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;87&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;Records&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;0&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Duplicates&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;0&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Warnings&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Después de crear el índice, el optimizador decide si conviene usarlo. El motor evalúa estadísticas, cardinalidad y costo estimado.&lt;/p&gt;
&lt;p&gt;Podemos inspeccionar los índices existentes con &lt;code&gt;SHOW INDEX&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SHOW&lt;/span&gt; &lt;span style="color:#c678dd"&gt;INDEX&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt; \&lt;span style="color:#c678dd"&gt;G&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;***************************&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;. &lt;span style="color:#c678dd"&gt;row&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;***************************&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;Table&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;Non_unique&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;Key_name&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;idx_email&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;Seq_in_index&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;Column_name&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;email&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;Collation&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;A&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;Cardinality&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;599&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;Sub_part&lt;/span&gt;: &lt;span style="color:#c678dd"&gt;NULL&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;Packed&lt;/span&gt;: &lt;span style="color:#c678dd"&gt;NULL&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;Null&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;YES&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;Index_type&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;BTREE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;5&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;06&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Y también podemos eliminarlos cuando dejan de aportar valor:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ALTER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;TABLE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;DROP&lt;/span&gt; &lt;span style="color:#c678dd"&gt;INDEX&lt;/span&gt; &lt;span style="color:#e06c75"&gt;idx_email&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;Query&lt;/span&gt; &lt;span style="color:#e06c75"&gt;OK&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;0&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#e06c75"&gt;affected&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;50&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;Records&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;0&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Duplicates&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;0&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Warnings&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Cada índice ocupa espacio y debe actualizarse cuando cambian las filas afectadas. Un índice acelera lecturas específicas, pero también puede encarecer escrituras como &lt;code&gt;INSERT&lt;/code&gt;, &lt;code&gt;UPDATE&lt;/code&gt; y &lt;code&gt;DELETE&lt;/code&gt;.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="índices-únicos"&gt;Índices únicos&lt;/h2&gt;
&lt;p&gt;Un &lt;strong&gt;índice único&lt;/strong&gt; cumple dos funciones: acelera búsquedas y evita valores duplicados en las columnas indexadas. Cada vez que insertas una fila o modificas la columna, el servidor valida si el valor ya existe.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ALTER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;TABLE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ADD&lt;/span&gt; &lt;span style="color:#c678dd"&gt;UNIQUE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;idx_email&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;email&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;Query&lt;/span&gt; &lt;span style="color:#e06c75"&gt;OK&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;0&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#e06c75"&gt;affected&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;64&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;Records&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;0&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Duplicates&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;0&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Warnings&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Si intentas insertar un cliente con un email ya registrado, el motor rechaza la operación:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;INSERT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;INTO&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;store_id&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;email&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;address_id&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;active&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;VALUES&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;,&lt;span style="color:#98c379"&gt;&amp;#39;ALAN&amp;#39;&lt;/span&gt;,&lt;span style="color:#98c379"&gt;&amp;#39;KAHN&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;ALAN.KAHN@sakilacustomer.org&amp;#39;&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;394&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;ERROR&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1062&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;23000&lt;/span&gt;): &lt;span style="color:#e06c75"&gt;Duplicate&lt;/span&gt; &lt;span style="color:#e06c75"&gt;entry&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;ALAN.KAHN@sakilacustomer.org&amp;#39;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;for&lt;/span&gt; &lt;span style="color:#c678dd"&gt;key&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;idx_email&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="índices-multicolumna"&gt;Índices multicolumna&lt;/h2&gt;
&lt;p&gt;También puedes crear índices que cubren varias columnas. Si buscas clientes por apellido y nombre, un índice compuesto puede ser más útil que dos índices separados.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ALTER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;TABLE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ADD&lt;/span&gt; &lt;span style="color:#c678dd"&gt;INDEX&lt;/span&gt; &lt;span style="color:#e06c75"&gt;idx_full_name&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;Query&lt;/span&gt; &lt;span style="color:#e06c75"&gt;OK&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;0&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#e06c75"&gt;affected&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;35&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;Records&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;0&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Duplicates&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;0&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Warnings&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El orden importa. Un índice &lt;code&gt;(last_name, first_name)&lt;/code&gt; ayuda a consultas que filtran por &lt;code&gt;last_name&lt;/code&gt; o por &lt;code&gt;last_name&lt;/code&gt; junto con &lt;code&gt;first_name&lt;/code&gt;. No ayuda igual a una consulta que filtra solo por &lt;code&gt;first_name&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="tipos-de-índices"&gt;Tipos de índices&lt;/h2&gt;
&lt;h3 id="índices-b-tree"&gt;Índices B-tree&lt;/h3&gt;
&lt;p&gt;Los índices &lt;strong&gt;B-tree&lt;/strong&gt; organizan los valores como árboles balanceados. Los &lt;strong&gt;branch nodes&lt;/strong&gt; sirven para navegar por rangos, mientras que los &lt;strong&gt;leaf nodes&lt;/strong&gt; almacenan los valores reales del índice.&lt;/p&gt;
&lt;p&gt;Branch nodes dirigen la búsqueda hacia el rango correcto; leaf nodes contienen las entradas finales asociadas a los valores indexados.&lt;/p&gt;
&lt;pre class="mermaid"&gt;flowchart TD
 root[&amp;#34;Nodo raíz&amp;lt;br/&amp;gt;A - M | N - Z&amp;#34;]
 b1[&amp;#34;A-C | D-F | G-I | J-M&amp;#34;]
 b2[&amp;#34;N-P | Q-S | T-V | W-Z&amp;#34;]
 root --&amp;gt; b1
 root --&amp;gt; b2
 b1 --&amp;gt; l1[&amp;#34;Barker&amp;lt;br/&amp;gt;Blake&amp;#34;]
 b1 --&amp;gt; l2[&amp;#34;Fleming&amp;lt;br/&amp;gt;Fowler&amp;#34;]
 b1 --&amp;gt; l3[&amp;#34;Gooding&amp;lt;br/&amp;gt;Grossman&amp;lt;br/&amp;gt;Hawthorne&amp;#34;]
 b1 --&amp;gt; l4[&amp;#34;Jameson&amp;lt;br/&amp;gt;Markham&amp;lt;br/&amp;gt;Mason&amp;#34;]
 b2 --&amp;gt; l5[&amp;#34;Parker&amp;lt;br/&amp;gt;Portman&amp;#34;]
 b2 --&amp;gt; l6[&amp;#34;Roberts&amp;lt;br/&amp;gt;Smith&amp;#34;]
 b2 --&amp;gt; l7[&amp;#34;Tucker&amp;lt;br/&amp;gt;Tulman&amp;lt;br/&amp;gt;Tyler&amp;#34;]
 b2 --&amp;gt; l8[&amp;#34;Ziegler&amp;#34;]
&lt;/pre&gt;

&lt;p&gt;Este tipo de índice funciona muy bien para columnas con muchos valores distintos, como &lt;code&gt;customer.last_name&lt;/code&gt;, fechas, identificadores externos o campos usados en rangos.&lt;/p&gt;
&lt;h3 id="índices-bitmap"&gt;Índices bitmap&lt;/h3&gt;
&lt;p&gt;Los &lt;strong&gt;bitmap indexes&lt;/strong&gt; están diseñados para columnas de baja cardinalidad, es decir, columnas con pocos valores posibles repetidos en muchas filas. Un ejemplo clásico es &lt;code&gt;customer.active&lt;/code&gt;, donde puede haber solo &lt;code&gt;1&lt;/code&gt; para activo y &lt;code&gt;0&lt;/code&gt; para inactivo.&lt;/p&gt;
&lt;p&gt;En lugar de mantener un árbol grande, el motor mantiene bitmaps por valor. Para consultar clientes inactivos, puede recorrer el bitmap del valor &lt;code&gt;0&lt;/code&gt; y localizar las filas correspondientes.&lt;/p&gt;
&lt;p&gt;Esta estrategia es compacta para baja cardinalidad, pero se degrada cuando la columna tiene demasiados valores distintos.&lt;/p&gt;
&lt;h3 id="índices-de-texto"&gt;Índices de texto&lt;/h3&gt;
&lt;p&gt;Cuando almacenas documentos o contenido largo, buscar palabras con un escaneo completo es costoso.&lt;/p&gt;
&lt;p&gt;MySQL y SQL Server ofrecen índices &lt;strong&gt;full-text&lt;/strong&gt;; Oracle incluye herramientas bajo &lt;strong&gt;Oracle Text&lt;/strong&gt;. Estos mecanismos están especializados para documentos y búsquedas textuales.&lt;/p&gt;
&lt;h2 id="cómo-se-usan-los-índices"&gt;Cómo se usan los índices&lt;/h2&gt;
&lt;p&gt;Los índices permiten acceder rápidamente a datos, pero el motor decide si usarlos según el plan de ejecución. Un índice creado no garantiza automáticamente una consulta más rápida.&lt;/p&gt;
&lt;p&gt;Observemos tres criterios prácticos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Crea índices alrededor de consultas frecuentes, no alrededor de columnas al azar.&lt;/li&gt;
&lt;li&gt;Evita indexar columnas con baja selectividad usando B-tree si el motor ofrece una estrategia mejor.&lt;/li&gt;
&lt;li&gt;Mide el impacto en escrituras, porque cada índice debe mantenerse actualizado.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="constraints-restricciones-de-integridad"&gt;Constraints: restricciones de integridad&lt;/h2&gt;
&lt;p&gt;Una &lt;strong&gt;constraint&lt;/strong&gt; es una restricción aplicada a una o más columnas de una tabla. Vive dentro del esquema y protege los datos desde la base.&lt;/p&gt;
&lt;p&gt;Los tipos principales son:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Primary key constraints&lt;/strong&gt;: identifican la columna o combinación de columnas que garantizan unicidad dentro de una tabla.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Foreign key constraints&lt;/strong&gt;: restringen una o más columnas para que contengan valores existentes en la primary key de otra tabla.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Unique constraints&lt;/strong&gt;: evitan duplicados en una o más columnas; una primary key es un caso especial de unicidad.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Check constraints&lt;/strong&gt;: restringen los valores permitidos para una columna según una condición.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Normalmente las constraints se crean junto con la tabla usando &lt;code&gt;CREATE TABLE&lt;/code&gt;. Este ejemplo del esquema Sakila combina primary key, índices y foreign keys:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;CREATE&lt;/span&gt; &lt;span style="color:#c678dd"&gt;TABLE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;SMALLINT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;UNSIGNED&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NOT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NULL&lt;/span&gt; &lt;span style="color:#e06c75"&gt;AUTO_INCREMENT&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;store_id&lt;/span&gt; &lt;span style="color:#e06c75"&gt;TINYINT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;UNSIGNED&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NOT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;VARCHAR&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;45&lt;/span&gt;) &lt;span style="color:#c678dd"&gt;NOT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;VARCHAR&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;45&lt;/span&gt;) &lt;span style="color:#c678dd"&gt;NOT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;email&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;VARCHAR&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;50&lt;/span&gt;) &lt;span style="color:#c678dd"&gt;DEFAULT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;address_id&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;SMALLINT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;UNSIGNED&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NOT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;active&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;BOOLEAN&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NOT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NULL&lt;/span&gt; &lt;span style="color:#c678dd"&gt;DEFAULT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;TRUE&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;create_date&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DATETIME&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NOT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;last_update&lt;/span&gt; &lt;span style="color:#c678dd"&gt;TIMESTAMP&lt;/span&gt; &lt;span style="color:#c678dd"&gt;DEFAULT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;CURRENT_TIMESTAMP&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#c678dd"&gt;UPDATE&lt;/span&gt; &lt;span style="color:#c678dd"&gt;CURRENT_TIMESTAMP&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;PRIMARY&lt;/span&gt; &lt;span style="color:#c678dd"&gt;KEY&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;KEY&lt;/span&gt; &lt;span style="color:#e06c75"&gt;idx_fk_store_id&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;store_id&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;KEY&lt;/span&gt; &lt;span style="color:#e06c75"&gt;idx_fk_address_id&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;address_id&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;KEY&lt;/span&gt; &lt;span style="color:#e06c75"&gt;idx_last_name&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;CONSTRAINT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fk_customer_address&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FOREIGN&lt;/span&gt; &lt;span style="color:#c678dd"&gt;KEY&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;address_id&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;REFERENCES&lt;/span&gt; &lt;span style="color:#e06c75"&gt;address&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;address_id&lt;/span&gt;) &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#c678dd"&gt;DELETE&lt;/span&gt; &lt;span style="color:#c678dd"&gt;RESTRICT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#c678dd"&gt;UPDATE&lt;/span&gt; &lt;span style="color:#c678dd"&gt;CASCADE&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;CONSTRAINT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fk_customer_store&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FOREIGN&lt;/span&gt; &lt;span style="color:#c678dd"&gt;KEY&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;store_id&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;REFERENCES&lt;/span&gt; &lt;span style="color:#e06c75"&gt;store&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;store_id&lt;/span&gt;) &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#c678dd"&gt;DELETE&lt;/span&gt; &lt;span style="color:#c678dd"&gt;RESTRICT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#c678dd"&gt;UPDATE&lt;/span&gt; &lt;span style="color:#c678dd"&gt;CASCADE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)&lt;span style="color:#e06c75"&gt;ENGINE&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;&lt;span style="color:#e06c75"&gt;InnoDB&lt;/span&gt; &lt;span style="color:#c678dd"&gt;DEFAULT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CHARSET&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;&lt;span style="color:#e06c75"&gt;utf8&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;También puedes agregar constraints después con &lt;code&gt;ALTER TABLE&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;ALTER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;TABLE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;ADD&lt;/span&gt; &lt;span style="color:#c678dd"&gt;CONSTRAINT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fk_customer_address&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FOREIGN&lt;/span&gt; &lt;span style="color:#c678dd"&gt;KEY&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;address_id&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;REFERENCES&lt;/span&gt; &lt;span style="color:#e06c75"&gt;address&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;address_id&lt;/span&gt;) &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#c678dd"&gt;DELETE&lt;/span&gt; &lt;span style="color:#c678dd"&gt;RESTRICT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#c678dd"&gt;UPDATE&lt;/span&gt; &lt;span style="color:#c678dd"&gt;CASCADE&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;ALTER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;TABLE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;ADD&lt;/span&gt; &lt;span style="color:#c678dd"&gt;CONSTRAINT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fk_customer_store&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FOREIGN&lt;/span&gt; &lt;span style="color:#c678dd"&gt;KEY&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;store_id&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;REFERENCES&lt;/span&gt; &lt;span style="color:#e06c75"&gt;store&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;store_id&lt;/span&gt;) &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#c678dd"&gt;DELETE&lt;/span&gt; &lt;span style="color:#c678dd"&gt;RESTRICT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#c678dd"&gt;UPDATE&lt;/span&gt; &lt;span style="color:#c678dd"&gt;CASCADE&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La cláusula &lt;code&gt;ON DELETE RESTRICT&lt;/code&gt; protege contra registros huérfanos cuando se intenta eliminar una fila padre.&lt;/p&gt;
&lt;p&gt;Para foreign keys, las acciones comunes ante borrados y actualizaciones son:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ON DELETE RESTRICT&lt;/code&gt;: impide borrar la fila padre si existen filas hijas relacionadas.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ON DELETE CASCADE&lt;/code&gt;: borra automáticamente las filas hijas cuando se borra la fila padre.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ON DELETE SET NULL&lt;/code&gt;: asigna &lt;code&gt;NULL&lt;/code&gt; en la foreign key de las filas hijas cuando se borra la fila padre.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ON UPDATE RESTRICT&lt;/code&gt;: impide actualizar la clave padre si hay filas hijas relacionadas.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ON UPDATE CASCADE&lt;/code&gt;: propaga el cambio de clave hacia las filas hijas.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ON UPDATE SET NULL&lt;/code&gt;: asigna &lt;code&gt;NULL&lt;/code&gt; en la foreign key de las filas hijas cuando cambia la clave padre.&lt;/li&gt;
&lt;/ul&gt;




 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;&lt;code&gt;CASCADE&lt;/code&gt; es potente, pero debe modelarse con cuidado. Una eliminación pequeña puede disparar borrados en varias tablas.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="conclusión-de-la-serie-sql"&gt;Conclusión de la serie SQL&lt;/h2&gt;
&lt;p&gt;Las transacciones, índices y constraints completan la base práctica para trabajar con SQL de forma profesional. Protegen operaciones compuestas, reducen el costo de acceso a datos y llevan reglas críticas al esquema.&lt;/p&gt;
&lt;p&gt;Con este artículo cerramos la serie de SQL. Para repasar desde el inicio, vuelve a: &lt;a href="https://blog.dacadev.com/programacion/sql/01-fundamentos-sql-select-from-where"



 


&gt;Fundamentos SQL: SELECT, FROM y WHERE&lt;/a&gt;. Desde ahí puedes recorrer consultas, filtros, joins, agrupaciones, subconsultas, vistas y estos mecanismos de integridad y rendimiento.&lt;/p&gt;</content:encoded></item><item><title>TypeScript: Depuración de errores y tsconfig.json</title><link>https://blog.dacadev.com/typescript/depuracion-y-tsconfig/</link><pubDate>Wed, 24 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/typescript/depuracion-y-tsconfig/</guid><dc:creator>Dacadev</dc:creator><category>programación</category><description>Configura el compilador de TypeScript con tsconfig.json: strict, noImplicitAny, removeComments, sourceMap y salida única para depurar y compilar mejor.</description><media:content url="https://blog.dacadev.com/images/typescript/debugging-tsconfig/banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#qué-es-tsconfigjson-y-para-qué-sirve"&gt;Qué es tsconfig.json y para qué sirve&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#opciones-recomendadas"&gt;Opciones recomendadas&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#sourcemap-depurar-el-código-original"&gt;sourceMap: depurar el código original&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#generar-un-único-archivo-de-salida"&gt;Generar un único archivo de salida&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#depurar-errores-con-eficacia"&gt;Depurar errores con eficacia&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#conclusión"&gt;Conclusión&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;





 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Artículo final de la serie sobre &lt;strong&gt;TypeScript&lt;/strong&gt;. Consolidaremos la configuración del compilador mediante &lt;code&gt;tsconfig.json&lt;/code&gt; y las opciones que facilitan la depuración y mejoran la calidad del código emitido.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;El archivo &lt;code&gt;tsconfig.json&lt;/code&gt; es el centro de control del compilador: define cómo TypeScript interpreta, verifica y transforma tu proyecto. Una configuración bien afinada no solo previene errores, sino que mejora la experiencia de depuración y la calidad del JavaScript resultante. Cerremos la serie dominando esta pieza. La referencia completa está en la &lt;a href="https://www.typescriptlang.org/docs/handbook/tsconfig-json.html"




 target="_blank"
 


&gt;documentación oficial de tsconfig.json&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="qué-es-tsconfigjson-y-para-qué-sirve"&gt;Qué es tsconfig.json y para qué sirve&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;tsconfig.json&lt;/code&gt; declara el comportamiento del compilador para todo el proyecto. Cuando se genera por primera vez, muchas opciones aparecen comentadas, y el valor mostrado en el comentario suele ser el recomendado por defecto.&lt;/p&gt;




 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;La presencia de un &lt;code&gt;tsconfig.json&lt;/code&gt; en un directorio marca la raíz de un proyecto TypeScript. Ejecutar &lt;code&gt;tsc&lt;/code&gt; sin argumentos hace que el compilador busque este archivo y compile según sus reglas.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="opciones-recomendadas"&gt;Opciones recomendadas&lt;/h2&gt;
&lt;p&gt;Estas opciones de &lt;code&gt;compilerOptions&lt;/code&gt; aportan el mayor valor en un proyecto profesional:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;strict&lt;/code&gt;: activa el conjunto completo de comprobaciones estrictas. Es la opción que más errores previene.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;noImplicitAny&lt;/code&gt;: prohíbe que TypeScript asigne &lt;code&gt;any&lt;/code&gt; de forma implícita cuando no puede inferir un tipo, obligándote a ser explícito.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;removeComments&lt;/code&gt;: elimina los comentarios del JavaScript compilado, produciendo una salida más limpia.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sourceMap&lt;/code&gt;: genera &lt;em&gt;source maps&lt;/em&gt; que enlazan el JavaScript emitido con tu código TypeScript original.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;&amp;#34;compilerOptions&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;&amp;#34;strict&amp;#34;&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;&amp;#34;noImplicitAny&amp;#34;&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;&amp;#34;removeComments&amp;#34;&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;&amp;#34;sourceMap&amp;#34;&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;&amp;#34;target&amp;#34;&lt;/span&gt;: &lt;span style="color:#98c379"&gt;&amp;#34;es2015&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;&amp;#34;module&amp;#34;&lt;/span&gt;: &lt;span style="color:#98c379"&gt;&amp;#34;commonjs&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;&amp;#34;outDir&amp;#34;&lt;/span&gt;: &lt;span style="color:#98c379"&gt;&amp;#34;dist&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;&amp;#34;include&amp;#34;&lt;/span&gt;: [&lt;span style="color:#98c379"&gt;&amp;#34;src&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



 
 





 


&lt;div class="notice tip"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z" /&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Tip&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;&lt;code&gt;strict&lt;/code&gt; es en realidad un &lt;em&gt;paraguas&lt;/em&gt; que activa varias comprobaciones, entre ellas &lt;code&gt;noImplicitAny&lt;/code&gt;, &lt;code&gt;strictNullChecks&lt;/code&gt; y &lt;code&gt;strictFunctionTypes&lt;/code&gt;. Habilitarlo desde el primer commit evita una migración costosa cuando el proyecto ya acumuló tipos implícitos.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="sourcemap-depurar-el-código-original"&gt;sourceMap: depurar el código original&lt;/h2&gt;
&lt;p&gt;Sin &lt;em&gt;source maps&lt;/em&gt;, cuando depuras en el navegador o en Node solo ves el JavaScript transpilado, que puede diferir notablemente de tu TypeScript. Con &lt;code&gt;sourceMap: true&lt;/code&gt;, el compilador genera archivos &lt;code&gt;.js.map&lt;/code&gt; que permiten al depurador mostrar tu código fuente original, colocar &lt;em&gt;breakpoints&lt;/em&gt; en él e inspeccionar variables con sus nombres reales.&lt;/p&gt;
&lt;p&gt;Esta opción es la diferencia entre depurar el código que escribiste y depurar el código que la máquina generó.&lt;/p&gt;
&lt;h2 id="generar-un-único-archivo-de-salida"&gt;Generar un único archivo de salida&lt;/h2&gt;
&lt;p&gt;Para ciertos escenarios —especialmente proyectos de frontend sin un &lt;em&gt;bundler&lt;/em&gt;— resulta útil concatenar toda la salida en un solo archivo JavaScript. Esto se logra con la opción &lt;code&gt;outFile&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;&amp;#34;compilerOptions&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;&amp;#34;outFile&amp;#34;&lt;/span&gt;: &lt;span style="color:#98c379"&gt;&amp;#34;./main.js&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;&amp;#34;sourceMap&amp;#34;&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;&amp;#34;removeComments&amp;#34;&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;&lt;code&gt;outFile&lt;/code&gt; solo funciona con los sistemas de módulos &lt;code&gt;amd&lt;/code&gt; y &lt;code&gt;system&lt;/code&gt;; no es compatible con &lt;code&gt;commonjs&lt;/code&gt; ni &lt;code&gt;esnext&lt;/code&gt;. En proyectos modernos, lo habitual es delegar el empaquetado a herramientas como webpack o esbuild en lugar de usar &lt;code&gt;outFile&lt;/code&gt;.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="depurar-errores-con-eficacia"&gt;Depurar errores con eficacia&lt;/h2&gt;
&lt;p&gt;El flujo de depuración en TypeScript combina las opciones anteriores con la lectura disciplinada de los mensajes del compilador:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cada error incluye un &lt;strong&gt;código&lt;/strong&gt; (por ejemplo &lt;code&gt;TS2345&lt;/code&gt;) que puedes buscar para entender su causa raíz.&lt;/li&gt;
&lt;li&gt;Con &lt;code&gt;strict&lt;/code&gt; activo, los errores afloran en compilación, antes de ejecutar el código.&lt;/li&gt;
&lt;li&gt;Con &lt;code&gt;sourceMap&lt;/code&gt;, los errores en tiempo de ejecución apuntan a tu TypeScript original, no al JavaScript emitido.&lt;/li&gt;
&lt;li&gt;El modo observador (&lt;code&gt;tsc --watch&lt;/code&gt;) reporta los errores de forma incremental mientras escribes.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="mermaid"&gt;flowchart LR
 A[Código TS] --&amp;gt; B[tsc con strict]
 B -- error de tipo --&amp;gt; C[Mensaje TSxxxx&amp;lt;br/&amp;gt;en compilación]
 B -- ok --&amp;gt; D[JS + sourceMap]
 D --&amp;gt; E[Runtime]
 E -- error --&amp;gt; F[Stack trace sobre TS&amp;lt;br/&amp;gt;gracias al sourceMap]
&lt;/pre&gt;

&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;tsconfig.json&lt;/code&gt; es la herramienta que transforma TypeScript de un transpilador genérico en un compilador afinado a tu proyecto. Activar &lt;code&gt;strict&lt;/code&gt; y &lt;code&gt;noImplicitAny&lt;/code&gt; maximiza la detección temprana de errores; &lt;code&gt;sourceMap&lt;/code&gt; hace que la depuración opere sobre tu código real; y &lt;code&gt;removeComments&lt;/code&gt; pule la salida. Dominar estas opciones cierra el ciclo: del tipado en el editor a la depuración en producción.&lt;/p&gt;
&lt;p&gt;Con esto concluye la serie sobre TypeScript. Has recorrido desde la instalación y los tipos básicos hasta los genéricos, los decoradores y la configuración del compilador: el conjunto de herramientas necesario para construir aplicaciones robustas y mantenibles con tipado estático.&lt;/p&gt;</content:encoded></item><item><title>SQL: Vistas (Views) para Abstraer y Asegurar tus Datos</title><link>https://blog.dacadev.com/programacion/sql/07-vistas-views/</link><pubDate>Tue, 23 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/programacion/sql/07-vistas-views/</guid><dc:creator>Dacadev</dc:creator><category>programación</category><description>Aprende a crear vistas en SQL con CREATE VIEW para abstraer consultas, proteger datos sensibles y entender cuándo una vista es actualizable.</description><media:content url="https://blog.dacadev.com/images/programming/sql/views/banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#qué-es-una-vista"&gt;Qué es una vista&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#por-qué-usar-vistas"&gt;Por qué usar vistas&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#seguridad-de-los-datos"&gt;Seguridad de los datos&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#agregar-datos"&gt;Agregar datos&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#esconder-complejidad"&gt;Esconder complejidad&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#datos-distribuidos-o-particionados"&gt;Datos distribuidos o particionados&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#vistas-actualizables"&gt;Vistas actualizables&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#actualizando-vistas-simples"&gt;Actualizando vistas simples&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#conclusión"&gt;Conclusión&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;p&gt;Cuando una base de datos crece, las consultas empiezan a acumular lógica de negocio, joins repetidos, filtros de seguridad y columnas calculadas. En ese punto, las &lt;strong&gt;vistas en SQL&lt;/strong&gt; se vuelven una herramienta clave: con &lt;code&gt;CREATE VIEW&lt;/code&gt; podemos encapsular una consulta y exponerla como si fuera una tabla lógica. En el artículo anterior vimos &lt;a href="https://blog.dacadev.com/programacion/sql/06-subqueries-subconsultas"



 


&gt;subqueries y subconsultas&lt;/a&gt;; ahora vamos a usar ese mismo nivel de composición para abstraer, asegurar y simplificar el acceso a datos.&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;En este artículo analizaremos qué es una vista, cómo crearla con &lt;code&gt;CREATE VIEW&lt;/code&gt;, por qué ayuda con seguridad, agregación, complejidad y datos distribuidos, y qué condiciones debe cumplir una vista para ser actualizable.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="qué-es-una-vista"&gt;Qué es una vista&lt;/h2&gt;
&lt;p&gt;Una &lt;strong&gt;vista&lt;/strong&gt; no es una tabla física. En términos prácticos, es una consulta guardada en la base de datos que puedes consultar con &lt;code&gt;SELECT&lt;/code&gt; como si fuera una tabla. La vista no almacena los registros por sí misma; almacena la definición del query que se ejecutará cuando accedas a ella.&lt;/p&gt;
&lt;p&gt;Esto reduce repetición y mejora la legibilidad. Si una consulta se usa todos los días, o si quieres exponer solo ciertas columnas a un equipo o aplicación, una vista ofrece una interfaz estable sobre las tablas base.&lt;/p&gt;
&lt;p&gt;Consideremos una vista sobre la tabla &lt;code&gt;customer&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;CREATE&lt;/span&gt; &lt;span style="color:#c678dd"&gt;VIEW&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_vw&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (&lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;email&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;AS&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;concat&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;substr&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;email&lt;/span&gt;,&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;,&lt;span style="color:#d19a66"&gt;2&lt;/span&gt;), &lt;span style="color:#98c379"&gt;&amp;#39;*****&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;substr&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;email&lt;/span&gt;, &lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;4&lt;/span&gt;)) &lt;span style="color:#e06c75"&gt;email&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;En este ejemplo, la vista &lt;code&gt;customer_vw&lt;/code&gt; expone &lt;code&gt;customer_id&lt;/code&gt;, &lt;code&gt;first_name&lt;/code&gt;, &lt;code&gt;last_name&lt;/code&gt; y &lt;code&gt;email&lt;/code&gt;. Observemos un detalle importante: el email no se entrega completo, sino enmascarado mediante &lt;code&gt;concat()&lt;/code&gt; y &lt;code&gt;substr()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Para usar la vista, la consultamos como cualquier otra relación:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;email&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_vw&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+--------------+-------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;email&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+--------------+-------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;MARY&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SMITH&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;MA&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;*****&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;org&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;PATRICIA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JOHNSON&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;PA&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;*****&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;org&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;LINDA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;WILLIAMS&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;LI&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;*****&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;org&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;BARBARA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JONES&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;BA&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;*****&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;org&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ELIZABETH&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;BROWN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;EL&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;*****&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;org&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ENRIQUE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FORSYTHE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;EN&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;*****&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;org&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FREDDIE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DUGGAN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FR&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;*****&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;org&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;WADE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DELVALLE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;WA&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;*****&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;org&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;AUSTIN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CINTRON&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;AU&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;*****&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;org&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+--------------+-------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;599&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;00&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La consulta queda más expresiva: en lugar de repetir el cálculo del email en cada reporte, centralizamos esa lógica en una vista.&lt;/p&gt;
&lt;p&gt;Si necesitas inspeccionar la estructura de una vista, puedes usar &lt;code&gt;DESCRIBE&lt;/code&gt; o su forma corta &lt;code&gt;DESC&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;describe&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_vw&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+----------------------+------+-----+---------+-------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Field&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;Type&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;Null&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;Key&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;Default&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Extra&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+----------------------+------+-----+---------+-------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;smallint&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;5&lt;/span&gt;) &lt;span style="color:#e06c75"&gt;unsigned&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NO&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;varchar&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;45&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NO&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NULL&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;varchar&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;45&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NO&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NULL&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;email&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;varchar&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;11&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;YES&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NULL&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+----------------------+------+-----+---------+-------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;4&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;00&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



 
 





 


&lt;div class="notice tip"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z" /&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Tip&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Puedes usar en vistas gran parte de lo que ya conoces de SQL: &lt;code&gt;WHERE&lt;/code&gt;, &lt;code&gt;ORDER BY&lt;/code&gt;, &lt;code&gt;GROUP BY&lt;/code&gt;, funciones, expresiones calculadas e incluso &lt;code&gt;JOIN&lt;/code&gt;. La vista encapsula la consulta; no elimina la necesidad de diseñarla correctamente.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="por-qué-usar-vistas"&gt;Por qué usar vistas&lt;/h2&gt;
&lt;p&gt;Las vistas son útiles cuando necesitas definir una capa de acceso estable entre las tablas reales y los consumidores de datos. Esa capa puede servir para seguridad, reporting, simplificación de consultas o unificación de datos.&lt;/p&gt;
&lt;h3 id="seguridad-de-los-datos"&gt;Seguridad de los datos&lt;/h3&gt;
&lt;p&gt;Cuando los usuarios consultan directamente las tablas base, pueden quedar expuestas columnas sensibles que no deberían estar disponibles para todos los perfiles. Una vista permite publicar solo las columnas necesarias y, si hace falta, transformar datos antes de mostrarlos.&lt;/p&gt;
&lt;p&gt;El ejemplo de &lt;code&gt;customer_vw&lt;/code&gt; aplica este patrón: el email se expone enmascarado. En una aplicación interna, podrías conceder permisos sobre la vista y evitar permisos directos sobre &lt;code&gt;customer&lt;/code&gt;. Así reduces superficie de exposición sin duplicar datos.&lt;/p&gt;
&lt;p&gt;Este enfoque también estabiliza contratos. Si la tabla base contiene más columnas en el futuro, los consumidores de la vista no las reciben automáticamente.&lt;/p&gt;
&lt;h3 id="agregar-datos"&gt;Agregar datos&lt;/h3&gt;
&lt;p&gt;Las vistas también funcionan bien para reportes o consultas agregadas. Si un equipo necesita revisar ventas por categoría de película, no tiene que escribir todos los &lt;code&gt;JOIN&lt;/code&gt; cada vez.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;CREATE&lt;/span&gt; &lt;span style="color:#c678dd"&gt;VIEW&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sales_by_film_category&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;AS&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;name&lt;/span&gt; &lt;span style="color:#c678dd"&gt;AS&lt;/span&gt; &lt;span style="color:#e06c75"&gt;category&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;SUM&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;p&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;amount&lt;/span&gt;) &lt;span style="color:#c678dd"&gt;AS&lt;/span&gt; &lt;span style="color:#e06c75"&gt;total_sales&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;payment&lt;/span&gt; &lt;span style="color:#c678dd"&gt;AS&lt;/span&gt; &lt;span style="color:#e06c75"&gt;p&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;INNER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental&lt;/span&gt; &lt;span style="color:#c678dd"&gt;AS&lt;/span&gt; &lt;span style="color:#e06c75"&gt;r&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#e06c75"&gt;p&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;rental_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;r&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;rental_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;INNER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;inventory&lt;/span&gt; &lt;span style="color:#c678dd"&gt;AS&lt;/span&gt; &lt;span style="color:#e06c75"&gt;i&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#e06c75"&gt;r&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;inventory_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;i&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;inventory_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;INNER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film&lt;/span&gt; &lt;span style="color:#c678dd"&gt;AS&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#e06c75"&gt;i&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;INNER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film_category&lt;/span&gt; &lt;span style="color:#c678dd"&gt;AS&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fc&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fc&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;INNER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;category&lt;/span&gt; &lt;span style="color:#c678dd"&gt;AS&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fc&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;category_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;category_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;GROUP&lt;/span&gt; &lt;span style="color:#c678dd"&gt;BY&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;ORDER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;BY&lt;/span&gt; &lt;span style="color:#e06c75"&gt;total_sales&lt;/span&gt; &lt;span style="color:#c678dd"&gt;DESC&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Esta vista encapsula una agregación de pagos por categoría. El consumidor puede ejecutar &lt;code&gt;SELECT * FROM sales_by_film_category;&lt;/code&gt; y enfocarse en el resultado, no en la mecánica de las relaciones.&lt;/p&gt;




 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Una vista con agregaciones no materializa necesariamente el resultado. En muchos motores, la consulta se evalúa al leer la vista. Si el reporte es costoso y se consulta con alta frecuencia, analiza índices, planes de ejecución o alternativas como vistas materializadas cuando tu motor las soporte.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h3 id="esconder-complejidad"&gt;Esconder complejidad&lt;/h3&gt;
&lt;p&gt;Otra ventaja importante es ocultar consultas complejas detrás de un nombre claro. Analicemos una vista que resume estadísticas de películas usando subconsultas:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;CREATE&lt;/span&gt; &lt;span style="color:#c678dd"&gt;VIEW&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film_stats&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;AS&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;title&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;description&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;rating&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (&lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;category&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;INNER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film_category&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fc&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;category_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fc&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;category_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fc&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt;) &lt;span style="color:#e06c75"&gt;category_name&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (&lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;count&lt;/span&gt;(&lt;span style="color:#56b6c2"&gt;*&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film_actor&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fa&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fa&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ) &lt;span style="color:#e06c75"&gt;num_actors&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (&lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;count&lt;/span&gt;(&lt;span style="color:#56b6c2"&gt;*&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;inventory&lt;/span&gt; &lt;span style="color:#e06c75"&gt;i&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;i&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ) &lt;span style="color:#e06c75"&gt;inventory_cnt&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (&lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;count&lt;/span&gt;(&lt;span style="color:#56b6c2"&gt;*&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;inventory&lt;/span&gt; &lt;span style="color:#e06c75"&gt;i&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;INNER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental&lt;/span&gt; &lt;span style="color:#e06c75"&gt;r&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#e06c75"&gt;i&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;inventory_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;r&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;inventory_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;i&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ) &lt;span style="color:#e06c75"&gt;num_rentals&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Esta consulta mezcla columnas directas, subqueries correlacionadas y conteos derivados. Usar &lt;code&gt;film_stats&lt;/code&gt; como interfaz simplifica el consumo y reduce errores de copia al reutilizar la lógica.&lt;/p&gt;
&lt;p&gt;También mejora la comunicación técnica. Un nombre como &lt;code&gt;film_stats&lt;/code&gt; expresa intención de negocio mejor que una consulta extensa pegada en múltiples servicios, dashboards o scripts.&lt;/p&gt;
&lt;h3 id="datos-distribuidos-o-particionados"&gt;Datos distribuidos o particionados&lt;/h3&gt;
&lt;p&gt;Las vistas pueden ayudar a unificar datos que viven en diferentes tablas. Si una tabla está particionada por año, por región o por tipo de entidad, una vista puede presentar una estructura más simple para quien consulta.&lt;/p&gt;
&lt;p&gt;El objetivo no es ocultar decisiones arquitectónicas críticas, sino evitar que cada consumidor tenga que conocer todos los detalles físicos del modelo. Una vista puede funcionar como una API interna de lectura dentro de la base de datos.&lt;/p&gt;
&lt;h2 id="vistas-actualizables"&gt;Vistas actualizables&lt;/h2&gt;
&lt;p&gt;Hasta ahora hemos usado vistas para leer datos. Sin embargo, algunos motores permiten ejecutar &lt;code&gt;UPDATE&lt;/code&gt;, &lt;code&gt;INSERT&lt;/code&gt; o &lt;code&gt;DELETE&lt;/code&gt; a través de una vista, siempre que la base de datos pueda mapear la operación de forma inequívoca hacia las tablas base.&lt;/p&gt;
&lt;p&gt;No todas las vistas son actualizables. Mientras más transformación tenga una vista, más difícil será determinar qué fila y qué columna real debe modificarse.&lt;/p&gt;
&lt;p&gt;Para que una vista sea actualizable, considera estas restricciones típicas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No se usan funciones de agregación como &lt;code&gt;max()&lt;/code&gt;, &lt;code&gt;min()&lt;/code&gt;, &lt;code&gt;avg()&lt;/code&gt;, &lt;code&gt;sum()&lt;/code&gt; o similares.&lt;/li&gt;
&lt;li&gt;La vista no utiliza cláusulas &lt;code&gt;GROUP BY&lt;/code&gt; ni &lt;code&gt;HAVING&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;No existen subconsultas en el &lt;code&gt;SELECT&lt;/code&gt; ni en el &lt;code&gt;FROM&lt;/code&gt;; y las subconsultas en el &lt;code&gt;WHERE&lt;/code&gt;, si existen, no hacen referencia a tablas del &lt;code&gt;FROM&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;La vista no utiliza &lt;code&gt;UNION&lt;/code&gt;, &lt;code&gt;UNION ALL&lt;/code&gt; ni &lt;code&gt;DISTINCT&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;La cláusula &lt;code&gt;FROM&lt;/code&gt; incluye al menos una tabla o una vista actualizable.&lt;/li&gt;
&lt;li&gt;Si hay más de una tabla o vista en el &lt;code&gt;FROM&lt;/code&gt;, se usan únicamente &lt;code&gt;INNER JOIN&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;




 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Las reglas exactas dependen del motor de base de datos. MySQL, PostgreSQL, SQL Server y Oracle tienen diferencias en sintaxis, permisos y casos soportados. Antes de depender de escrituras sobre vistas en producción, valida el comportamiento en tu motor específico.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h3 id="actualizando-vistas-simples"&gt;Actualizando vistas simples&lt;/h3&gt;
&lt;p&gt;Supongamos nuevamente la vista &lt;code&gt;customer_vw&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;CREATE&lt;/span&gt; &lt;span style="color:#c678dd"&gt;VIEW&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_vw&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (&lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;email&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;AS&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;concat&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;substr&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;email&lt;/span&gt;,&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;,&lt;span style="color:#d19a66"&gt;2&lt;/span&gt;), &lt;span style="color:#98c379"&gt;&amp;#39;*****&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;substr&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;email&lt;/span&gt;, &lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;4&lt;/span&gt;)) &lt;span style="color:#e06c75"&gt;email&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Podemos actualizar una columna directa de la tabla base, como &lt;code&gt;last_name&lt;/code&gt;, usando la vista:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;UPDATE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_vw&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SET&lt;/span&gt; &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;SMITH-ALLEN&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;Query&lt;/span&gt; &lt;span style="color:#e06c75"&gt;OK&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#c678dd"&gt;row&lt;/span&gt; &lt;span style="color:#e06c75"&gt;affected&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;11&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;Rows&lt;/span&gt; &lt;span style="color:#e06c75"&gt;matched&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Changed&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Warnings&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La operación funciona porque &lt;code&gt;last_name&lt;/code&gt; corresponde directamente a una columna actualizable de &lt;code&gt;customer&lt;/code&gt;. La vista actúa como una capa de acceso, pero el motor sabe qué valor modificar.&lt;/p&gt;
&lt;p&gt;En cambio, si intentamos actualizar &lt;code&gt;email&lt;/code&gt;, la operación falla:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;UPDATE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_vw&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SET&lt;/span&gt; &lt;span style="color:#e06c75"&gt;email&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;MARY.SMITH-ALLEN@sakilacustomer.org&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;ERROR&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1348&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;HY000&lt;/span&gt;): &lt;span style="color:#c678dd"&gt;Column&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;email&amp;#39;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;is&lt;/span&gt; &lt;span style="color:#c678dd"&gt;not&lt;/span&gt; &lt;span style="color:#e06c75"&gt;updatable&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La razón es que &lt;code&gt;email&lt;/code&gt; en la vista no es la columna original; es una expresión calculada con &lt;code&gt;concat()&lt;/code&gt; y &lt;code&gt;substr()&lt;/code&gt;. El motor no puede inferir cómo convertir el valor nuevo en una actualización válida de la columna base.&lt;/p&gt;
&lt;p&gt;También debes tener cuidado con &lt;code&gt;INSERT&lt;/code&gt;. Insertar a través de una vista falla cuando la vista no expone todas las columnas &lt;code&gt;NOT NULL&lt;/code&gt; de la tabla base, por lo que el &lt;code&gt;INSERT&lt;/code&gt; no puede proporcionar valores para ellas. Si esas columnas no tienen &lt;code&gt;DEFAULT&lt;/code&gt;, el motor no tiene forma segura de completar la fila.&lt;/p&gt;
&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;Las vistas en SQL son una herramienta de diseño para crear interfaces de datos más limpias. Con &lt;code&gt;CREATE VIEW&lt;/code&gt; puedes encapsular consultas repetidas, proteger columnas sensibles, construir reportes agregados y esconder complejidad sin duplicar información.&lt;/p&gt;
&lt;p&gt;También es importante reconocer sus límites. Una vista no reemplaza un buen diseño de índices, no siempre mejora rendimiento y no siempre permite escritura. Cuando una vista incluye agregaciones, expresiones calculadas, &lt;code&gt;DISTINCT&lt;/code&gt;, &lt;code&gt;UNION&lt;/code&gt; o subconsultas complejas, normalmente debes tratarla como una interfaz de lectura.&lt;/p&gt;
&lt;p&gt;Como siguiente paso de la serie, analizaremos cómo proteger la consistencia y el rendimiento de operaciones más críticas con &lt;a href="https://blog.dacadev.com/programacion/sql/08-transacciones-indices-constraints"



 


&gt;transacciones, índices y constraints&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title>TypeScript: Namespaces, módulos e importaciones</title><link>https://blog.dacadev.com/typescript/namespaces-y-modulos/</link><pubDate>Tue, 23 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/typescript/namespaces-y-modulos/</guid><dc:creator>Dacadev</dc:creator><category>programación</category><description>Organiza tu código en TypeScript con namespaces y módulos ES: exportaciones nombradas, import, alias, export default y archivos barrel con index.ts.</description><media:content url="https://blog.dacadev.com/images/typescript/namespaces-modules/banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#namespaces"&gt;Namespaces&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#módulos-export-e-import"&gt;Módulos: export e import&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#archivos-barrel-centralizar-exportaciones"&gt;Archivos barrel: centralizar exportaciones&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#export-alias"&gt;Export alias&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#export-default"&gt;Export default&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#del-código-a-un-bundle"&gt;Del código a un bundle&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#conclusión"&gt;Conclusión&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;





 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Décimo artículo de la serie sobre &lt;strong&gt;TypeScript&lt;/strong&gt;. Organizaremos el código con namespaces y módulos ES: exportaciones nombradas, &lt;code&gt;import&lt;/code&gt;, alias, &lt;code&gt;export default&lt;/code&gt; y archivos &lt;em&gt;barrel&lt;/em&gt;.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;A medida que un proyecto crece, la organización del código deja de ser un detalle estético para convertirse en un factor de mantenibilidad. TypeScript ofrece dos mecanismos para estructurar el código: los &lt;strong&gt;namespaces&lt;/strong&gt; —agrupadores internos— y los &lt;strong&gt;módulos ES&lt;/strong&gt; —el estándar moderno basado en &lt;code&gt;export&lt;/code&gt; e &lt;code&gt;import&lt;/code&gt;. Analicemos cuándo usar cada uno.&lt;/p&gt;
&lt;h2 id="namespaces"&gt;Namespaces&lt;/h2&gt;
&lt;p&gt;Un namespace agrupa funciones, clases y variables relacionadas bajo un identificador común, exponiendo solo lo que marques con &lt;code&gt;export&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;namespace&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Validations&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;export&lt;/span&gt; &lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;validateText&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;text&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#c678dd"&gt;boolean&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;text&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;length&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;export&lt;/span&gt; &lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;validateDate&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;myDate&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;Date&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#c678dd"&gt;boolean&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;!&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;isNaN&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;myDate&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;valueOf&lt;/span&gt;())
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;Validations&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;validateText&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;hola mundo&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Solo los miembros exportados (&lt;code&gt;validateText&lt;/code&gt;, &lt;code&gt;validateDate&lt;/code&gt;) son accesibles desde fuera mediante la notación &lt;code&gt;Namespace.miembro&lt;/code&gt;.&lt;/p&gt;




 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Los namespaces se usan cada vez menos en el desarrollo de aplicaciones, donde los módulos ES son el estándar. Sin embargo, siguen presentes como base interna de muchos frameworks y de archivos de definición de tipos (&lt;code&gt;.d.ts&lt;/code&gt;).&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="módulos-export-e-import"&gt;Módulos: export e import&lt;/h2&gt;
&lt;p&gt;Los módulos son el mecanismo recomendado. Cada archivo es un módulo y expone su API con &lt;code&gt;export&lt;/code&gt;; otros archivos la consumen con &lt;code&gt;import&lt;/code&gt;. Para exportar, antepón &lt;code&gt;export&lt;/code&gt; a la declaración:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// classes/Heros.ts
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;export&lt;/span&gt; &lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Hero&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;constructor&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;public&lt;/span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;public&lt;/span&gt; &lt;span style="color:#e06c75"&gt;powerID&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;public&lt;/span&gt; &lt;span style="color:#e06c75"&gt;age&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ) {}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Y para consumirla, usa &lt;code&gt;import&lt;/code&gt; con desestructuración de los miembros nombrados:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// index.ts
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;Hero&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;./classes/Heros&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;spiderman&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;Hero&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#c678dd"&gt;new&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Hero&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;Spiderman&amp;#39;&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;100&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;23&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="archivos-barrel-centralizar-exportaciones"&gt;Archivos barrel: centralizar exportaciones&lt;/h2&gt;
&lt;p&gt;Cuando una carpeta agrupa varios módulos relacionados, importarlos uno a uno desde rutas distintas se vuelve tedioso. Un archivo &lt;em&gt;barrel&lt;/em&gt; —convencionalmente un &lt;code&gt;index.ts&lt;/code&gt; dentro de la carpeta— reexporta todo desde un único punto de entrada:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// interfaces/index.ts
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;export&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;Hero&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;./hero&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;export&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;Villain&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;./villain&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Esto permite importar múltiples miembros refiriéndote solo a la carpeta, lo que simplifica las rutas y desacopla a los consumidores de la estructura interna:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;Hero&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;Villain&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;./interfaces&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre class="mermaid"&gt;flowchart LR
 H[hero.ts] --&amp;gt; I[index.ts barrel]
 V[villain.ts] --&amp;gt; I
 I --&amp;gt; C[consumidor: import desde &amp;#39;./interfaces&amp;#39;]
&lt;/pre&gt;

&lt;h2 id="export-alias"&gt;Export alias&lt;/h2&gt;
&lt;p&gt;Un alias renombra un miembro al importarlo, lo que resuelve colisiones de nombres entre módulos distintos. Se usa la palabra clave &lt;code&gt;as&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;powers&lt;/span&gt; &lt;span style="color:#c678dd"&gt;as&lt;/span&gt; &lt;span style="color:#e06c75"&gt;poderes&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;./data/powers&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;poderes&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="export-default"&gt;Export default&lt;/h2&gt;
&lt;p&gt;Una exportación por defecto designa el valor principal de un módulo. Se importa sin llaves y puede combinarse con importaciones nombradas en la misma línea:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// data/powers.ts
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;export&lt;/span&gt; &lt;span style="color:#c678dd"&gt;default&lt;/span&gt; &lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Powers&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#7f848e"&gt;/* ... */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;export&lt;/span&gt; &lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;powers&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; [&lt;span style="color:#98c379"&gt;&amp;#39;fuerza&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;velocidad&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Powers&lt;/span&gt;, { &lt;span style="color:#e06c75"&gt;powers&lt;/span&gt; &lt;span style="color:#c678dd"&gt;as&lt;/span&gt; &lt;span style="color:#e06c75"&gt;poderes&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;./data/powers&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;Powers&lt;/code&gt; corresponde a la exportación por defecto y &lt;code&gt;poderes&lt;/code&gt; a una exportación nombrada renombrada con alias.&lt;/p&gt;




 
 





 


&lt;div class="notice tip"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z" /&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Tip&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Prefiere las exportaciones nombradas frente a &lt;code&gt;export default&lt;/code&gt; en bases de código grandes: facilitan el &lt;em&gt;autocompletado&lt;/em&gt;, el &lt;em&gt;refactoring&lt;/em&gt; automático y mantienen nombres consistentes entre el módulo y sus consumidores.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="del-código-a-un-bundle"&gt;Del código a un bundle&lt;/h2&gt;
&lt;p&gt;Los módulos resuelven la organización en tiempo de desarrollo, pero el navegador necesita servir el resultado de forma eficiente. Empaquetadores como &lt;strong&gt;webpack&lt;/strong&gt; combinan todos los módulos en uno o pocos archivos optimizados, resolviendo el grafo de dependencias que tejen tus &lt;code&gt;import&lt;/code&gt;. TypeScript se integra en este flujo transpilando primero a JavaScript y dejando que el bundler se encargue del empaquetado final.&lt;/p&gt;
&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;Estructurar el código es una decisión de arquitectura. Los namespaces agrupan elementos internos y persisten en definiciones de tipos, pero el estándar moderno son los módulos ES con &lt;code&gt;export&lt;/code&gt;/&lt;code&gt;import&lt;/code&gt;. Los archivos &lt;em&gt;barrel&lt;/em&gt; centralizan las exportaciones, los alias resuelven colisiones de nombres y &lt;code&gt;export default&lt;/code&gt; designa el valor principal de un módulo.&lt;/p&gt;
&lt;p&gt;En el artículo final de la serie consolidaremos la configuración del compilador y la &lt;strong&gt;depuración de errores&lt;/strong&gt; mediante &lt;code&gt;tsconfig.json&lt;/code&gt;.&lt;/p&gt;</content:encoded></item><item><title>TypeScript: Decoradores y metaprogramación</title><link>https://blog.dacadev.com/typescript/decoradores/</link><pubDate>Mon, 22 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/typescript/decoradores/</guid><dc:creator>Dacadev</dc:creator><category>programación</category><description>Aprende a usar decoradores en TypeScript: decoradores de clase, de fábrica, de método y de propiedad para extender comportamiento con metaprogramación.</description><media:content url="https://blog.dacadev.com/images/typescript/decorators/banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#decoradores-de-clase"&gt;Decoradores de clase&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#decoradores-de-fábrica"&gt;Decoradores de fábrica&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#decoradores-de-método"&gt;Decoradores de método&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#decoradores-de-propiedad"&gt;Decoradores de propiedad&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#conclusión"&gt;Conclusión&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;





 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Noveno artículo de la serie sobre &lt;strong&gt;TypeScript&lt;/strong&gt;. Estudiaremos los decoradores: funciones que se ejecutan en la definición de clases, métodos y propiedades para extender su comportamiento sin modificar su código original.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Un &lt;strong&gt;decorador en TypeScript&lt;/strong&gt; es una función que se ejecuta en tiempo de transpilación y permite expandir la funcionalidad de un objeto —clase, método o propiedad— de forma declarativa. Frameworks como Angular o NestJS apoyan gran parte de su ergonomía en este mecanismo. Analicemos cada variante con ejemplos prácticos. Puedes consultar la referencia completa en la &lt;a href="https://www.typescriptlang.org/docs/handbook/decorators.html"




 target="_blank"
 


&gt;documentación oficial de decoradores&lt;/a&gt;.&lt;/p&gt;




 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Los decoradores se colocan con la sintaxis &lt;code&gt;@nombre&lt;/code&gt; justo antes del elemento a decorar. Por convención se declaran con &lt;code&gt;function&lt;/code&gt; —en lugar de arrow functions— para distinguirlos visualmente de las funciones ordinarias.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="decoradores-de-clase"&gt;Decoradores de clase&lt;/h2&gt;
&lt;p&gt;Un decorador de clase recibe el constructor y se ejecuta &lt;strong&gt;una sola vez&lt;/strong&gt;, en el momento en que se define la clase —no al crear cada instancia:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;function&lt;/span&gt; &lt;span style="color:#e06c75"&gt;printToConsole&lt;/span&gt;(&lt;span style="color:#c678dd"&gt;constructor&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;Function&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#c678dd"&gt;constructor&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;@printToConsole&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;export&lt;/span&gt; &lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Pokemon&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;public&lt;/span&gt; &lt;span style="color:#e06c75"&gt;publicApi&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;https://pokeapi.co&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;constructor&lt;/span&gt;(&lt;span style="color:#c678dd"&gt;public&lt;/span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;) {}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Al crear varias instancias, el decorador no vuelve a ejecutarse: su efecto ocurre en la definición, no en la instanciación.&lt;/p&gt;
&lt;h2 id="decoradores-de-fábrica"&gt;Decoradores de fábrica&lt;/h2&gt;
&lt;p&gt;Un decorador de fábrica es una función que &lt;strong&gt;retorna&lt;/strong&gt; el decorador real. Esto permite parametrizar el comportamiento, aceptando argumentos que controlan cómo se aplica:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;function&lt;/span&gt; &lt;span style="color:#e06c75"&gt;printToConsole&lt;/span&gt;(&lt;span style="color:#c678dd"&gt;constructor&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;Function&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#c678dd"&gt;constructor&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;printToConsoleConditional&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;print&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;boolean&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;true&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;Function&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;print&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;?&lt;/span&gt; &lt;span style="color:#e06c75"&gt;printToConsole&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; () &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;@printToConsoleConditional&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;false&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;export&lt;/span&gt; &lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Pokemon&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;public&lt;/span&gt; &lt;span style="color:#e06c75"&gt;publicApi&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;https://pokeapi.co&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;constructor&lt;/span&gt;(&lt;span style="color:#c678dd"&gt;public&lt;/span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;) {}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Un patrón habitual es sellar el prototipo para impedir que se alteren sus propiedades en tiempo de ejecución:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;blockPrototype&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#c678dd"&gt;function&lt;/span&gt; (&lt;span style="color:#c678dd"&gt;constructor&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;Function&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;Object&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;seal&lt;/span&gt;(&lt;span style="color:#c678dd"&gt;constructor&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;Object&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;seal&lt;/span&gt;(&lt;span style="color:#c678dd"&gt;constructor&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;prototype&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;@blockPrototype&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;@printToConsoleConditional&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;false&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;export&lt;/span&gt; &lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Pokemon&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#7f848e"&gt;// ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



 
 





 


&lt;div class="notice tip"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z" /&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Tip&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Cuando aplicas múltiples decoradores, se ejecutan de forma secuencial &lt;strong&gt;de abajo hacia arriba&lt;/strong&gt;. En el ejemplo anterior, primero corre &lt;code&gt;printToConsoleConditional&lt;/code&gt; y luego &lt;code&gt;blockPrototype&lt;/code&gt;.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="decoradores-de-método"&gt;Decoradores de método&lt;/h2&gt;
&lt;p&gt;Un decorador de método recibe tres argumentos —el objeto al que pertenece, el nombre del método y su &lt;code&gt;PropertyDescriptor&lt;/code&gt;— y puede inspeccionar o &lt;strong&gt;reemplazar&lt;/strong&gt; por completo el comportamiento del método. Aquí lo usamos para validar argumentos:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;function&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CheckValidPokemonId() {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#c678dd"&gt;function&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;target&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;any&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;propertyKey&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;descriptor&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;PropertyDescriptor&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;originalMethod&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;descriptor&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;value&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;descriptor&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;value&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;id&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;if&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;||&lt;/span&gt; &lt;span style="color:#e06c75"&gt;id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#d19a66"&gt;100&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;error&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;El id del pokemon debe estar entre 1 y 100&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;originalMethod&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;id&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;export&lt;/span&gt; &lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Pokemon&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;public&lt;/span&gt; &lt;span style="color:#e06c75"&gt;publicApi&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;https://pokeapi.co&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;constructor&lt;/span&gt;(&lt;span style="color:#c678dd"&gt;public&lt;/span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;) {}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;@CheckValidPokemonId&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;savePokemonToDB&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;id&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;`Pokemon guardado en la base de datos &lt;/span&gt;&lt;span style="color:#98c379"&gt;${&lt;/span&gt;&lt;span style="color:#e06c75"&gt;id&lt;/span&gt;&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt;`&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Al envolver &lt;code&gt;originalMethod&lt;/code&gt;, el decorador intercepta la llamada, valida el &lt;code&gt;id&lt;/code&gt; y solo delega al método original cuando el valor es válido. Este es el fundamento de las validaciones declarativas de muchos frameworks.&lt;/p&gt;
&lt;h2 id="decoradores-de-propiedad"&gt;Decoradores de propiedad&lt;/h2&gt;
&lt;p&gt;Un decorador de propiedad recibe el objeto y el nombre de la propiedad, y puede alterar cómo se lee y escribe. Es útil para controlar el acceso a datos —recordando que JavaScript no tiene propiedades verdaderamente privadas en runtime:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;function&lt;/span&gt; &lt;span style="color:#e06c75"&gt;readOnly&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;isWriteable&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;boolean&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;true&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;Function&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#c678dd"&gt;function&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;target&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;any&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;propertyKey&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;descriptor&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;PropertyDescriptor&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;get&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Daca code&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt;(&lt;span style="color:#c678dd"&gt;this&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;val&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;Object&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;defineProperty&lt;/span&gt;(&lt;span style="color:#c678dd"&gt;this&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;propertyKey&lt;/span&gt;, {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;value&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;val&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;writable&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;!&lt;/span&gt;&lt;span style="color:#e06c75"&gt;isWriteable&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;enumerable&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;descriptor&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;export&lt;/span&gt; &lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Pokemon&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;@readOnly&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;false&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;private&lt;/span&gt; &lt;span style="color:#e06c75"&gt;publicApi&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;https://pokeapi.co&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;constructor&lt;/span&gt;(&lt;span style="color:#c678dd"&gt;public&lt;/span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;) {}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El decorador define un &lt;code&gt;get&lt;/code&gt;/&lt;code&gt;set&lt;/code&gt; personalizado que gobierna por completo el acceso a &lt;code&gt;publicApi&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;Los decoradores aportan metaprogramación declarativa a TypeScript: el decorador de clase actúa sobre el constructor una única vez, el de fábrica parametriza el comportamiento, el de método intercepta y reemplaza llamadas, y el de propiedad controla la lectura y escritura. Componerlos en cadena —respetando su orden de ejecución— es lo que habilita las APIs elegantes de frameworks modernos.&lt;/p&gt;
&lt;p&gt;En el próximo artículo organizaremos el código con &lt;strong&gt;namespaces y módulos&lt;/strong&gt;: &lt;code&gt;export&lt;/code&gt;, &lt;code&gt;import&lt;/code&gt;, alias y exportaciones por defecto.&lt;/p&gt;</content:encoded></item><item><title>TypeScript: Tipos avanzados, subtipos y varianza</title><link>https://blog.dacadev.com/typescript/tipos-avanzados/</link><pubDate>Sun, 21 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/typescript/tipos-avanzados/</guid><dc:creator>Dacadev</dc:creator><category>programación</category><description>Comprende la jerarquía de tipos de TypeScript: subtipos y supertipos, los tipos top y bottom (unknown y never), null, undefined, void y la varianza.</description><media:content url="https://blog.dacadev.com/images/typescript/advanced-types/banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#subtipos"&gt;Subtipos&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#supertipos"&gt;Supertipos&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#la-jerarquía-de-tipos"&gt;La jerarquía de tipos&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#los-tipos-especiales-null-undefined-void-y-never"&gt;Los tipos especiales: null, undefined, void y never&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#varianza"&gt;Varianza&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#conclusión"&gt;Conclusión&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;





 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Octavo artículo de la serie sobre &lt;strong&gt;TypeScript&lt;/strong&gt;. Abordaremos la teoría que sustenta el sistema de tipos: subtipos, supertipos, la jerarquía completa, los tipos &lt;code&gt;unknown&lt;/code&gt; y &lt;code&gt;never&lt;/code&gt;, y la varianza.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Comprender la &lt;strong&gt;relación entre tipos&lt;/strong&gt; es lo que separa a quien usa TypeScript de quien lo domina. El compilador decide qué asignaciones son válidas aplicando reglas de subtipado y varianza. Una vez interiorizadas estas reglas, los errores del typechecker dejan de ser obstáculos crípticos y se convierten en información precisa sobre el diseño de tus tipos.&lt;/p&gt;
&lt;h2 id="subtipos"&gt;Subtipos&lt;/h2&gt;
&lt;p&gt;La regla fundamental del subtipado se enuncia así:&lt;/p&gt;




 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Si tienes un tipo &lt;code&gt;A&lt;/code&gt; y un tipo &lt;code&gt;B&lt;/code&gt; donde &lt;code&gt;B&lt;/code&gt; es &lt;strong&gt;subtipo&lt;/strong&gt; de &lt;code&gt;A&lt;/code&gt;, entonces puedes usar &lt;code&gt;B&lt;/code&gt; en cualquier lugar donde se espere un &lt;code&gt;A&lt;/code&gt;.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Algunas relaciones de subtipo en TypeScript:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Array&lt;/code&gt; es subtipo de &lt;code&gt;Object&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Tuple&lt;/code&gt; es subtipo de &lt;code&gt;Array&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Todo es subtipo de &lt;code&gt;any&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;never&lt;/code&gt; es subtipo de todo.&lt;/li&gt;
&lt;li&gt;Si una clase &lt;code&gt;Bird&lt;/code&gt; extiende &lt;code&gt;Animal&lt;/code&gt;, entonces &lt;code&gt;Bird&lt;/code&gt; es subtipo de &lt;code&gt;Animal&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Aplicado a la práctica, esto significa que donde se necesite un &lt;code&gt;Object&lt;/code&gt; puedes usar un &lt;code&gt;Array&lt;/code&gt;; donde se necesite un &lt;code&gt;Array&lt;/code&gt; puedes usar una &lt;code&gt;Tuple&lt;/code&gt;; y donde se necesite un &lt;code&gt;Animal&lt;/code&gt; puedes usar un &lt;code&gt;Bird&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="supertipos"&gt;Supertipos&lt;/h2&gt;
&lt;p&gt;Un supertipo es la relación inversa:&lt;/p&gt;




 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Si tienes un tipo &lt;code&gt;A&lt;/code&gt; y un tipo &lt;code&gt;B&lt;/code&gt; donde &lt;code&gt;B&lt;/code&gt; es &lt;strong&gt;supertipo&lt;/strong&gt; de &lt;code&gt;A&lt;/code&gt;, entonces puedes usar &lt;code&gt;A&lt;/code&gt; en cualquier lugar donde se espere un &lt;code&gt;B&lt;/code&gt;.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Las relaciones de supertipo reflejan en espejo a las anteriores:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Array&lt;/code&gt; es supertipo de &lt;code&gt;Tuple&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Object&lt;/code&gt; es supertipo de &lt;code&gt;Array&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;any&lt;/code&gt; es supertipo de todo.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Animal&lt;/code&gt; es supertipo de &lt;code&gt;Bird&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="la-jerarquía-de-tipos"&gt;La jerarquía de tipos&lt;/h2&gt;
&lt;p&gt;Todas estas relaciones forman una jerarquía con un tipo en la cúspide (&lt;em&gt;top type&lt;/em&gt;) y otro en el fondo (&lt;em&gt;bottom type&lt;/em&gt;):&lt;/p&gt;
&lt;pre class="mermaid"&gt;flowchart TD
 Unknown[unknown - top type] --&amp;gt; Any[any]
 Any --&amp;gt; Number
 Any --&amp;gt; BigInt
 Any --&amp;gt; Boolean
 Any --&amp;gt; String
 Any --&amp;gt; Symbol
 Any --&amp;gt; Object
 Any --&amp;gt; Void
 Any --&amp;gt; Null
 Any --&amp;gt; Undefined
 Object --&amp;gt; Array
 Array --&amp;gt; Tuple
 Object --&amp;gt; Function
 Number --&amp;gt; Never[never - bottom type]
 String --&amp;gt; Never
 Boolean --&amp;gt; Never
 Object --&amp;gt; Never
 Tuple --&amp;gt; Never
&lt;/pre&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;unknown&lt;/code&gt;&lt;/strong&gt; es el &lt;em&gt;top type&lt;/em&gt;: todo es asignable a él, pero no permite operar sin acotar primero.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;never&lt;/code&gt;&lt;/strong&gt; es el &lt;em&gt;bottom type&lt;/em&gt;: es subtipo de cualquier otro tipo y representa lo que nunca ocurre.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="los-tipos-especiales-null-undefined-void-y-never"&gt;Los tipos especiales: null, undefined, void y never&lt;/h2&gt;
&lt;p&gt;Estos cuatro tipos modelan la ausencia de valor con matices distintos:&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Tipo&lt;/th&gt;
 &lt;th&gt;Significado&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;null&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Ausencia explícita de valor&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;undefined&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Variable que aún no recibió un valor&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;void&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Función que no tiene sentencia &lt;code&gt;return&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;never&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Función que nunca retorna&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;La distinción entre &lt;code&gt;void&lt;/code&gt; y &lt;code&gt;never&lt;/code&gt; es sutil pero importante. Una función &lt;code&gt;void&lt;/code&gt; termina sin devolver nada útil; una función &lt;code&gt;never&lt;/code&gt; no termina en absoluto, ya sea porque lanza una excepción o porque entra en un bucle infinito:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// void: termina, no retorna valor
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;function&lt;/span&gt; &lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;msg&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#c678dd"&gt;void&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;msg&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// never: nunca completa su ejecución
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;function&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fail&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;message&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;never&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;throw&lt;/span&gt; &lt;span style="color:#c678dd"&gt;new&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;Error&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;message&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;function&lt;/span&gt; &lt;span style="color:#e06c75"&gt;loopForever&lt;/span&gt;()&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;never&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;while&lt;/span&gt; (&lt;span style="color:#e5c07b"&gt;true&lt;/span&gt;) {}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



 
 





 


&lt;div class="notice tip"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z" /&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Tip&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;&lt;code&gt;never&lt;/code&gt; es especialmente útil en la verificación de exhaustividad: si un &lt;code&gt;switch&lt;/code&gt; cubre todos los casos de una unión, la rama &lt;code&gt;default&lt;/code&gt; puede asignar el valor a un &lt;code&gt;never&lt;/code&gt;, y el compilador detectará en tiempo de compilación cualquier caso olvidado al ampliar la unión.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="varianza"&gt;Varianza&lt;/h2&gt;
&lt;p&gt;Determinar si un tipo es sub o supertipo de otro no siempre es evidente, sobre todo al combinar estructuras y funciones. TypeScript dispone de una notación formal para razonar sobre estas relaciones:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;A &amp;lt;: B&lt;/code&gt; significa &amp;ldquo;&lt;code&gt;A&lt;/code&gt; es subtipo de, o el mismo tipo que, &lt;code&gt;B&lt;/code&gt;&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;A &amp;gt;: B&lt;/code&gt; significa &amp;ldquo;&lt;code&gt;A&lt;/code&gt; es supertipo de, o el mismo tipo que, &lt;code&gt;B&lt;/code&gt;&amp;rdquo;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La &lt;strong&gt;varianza&lt;/strong&gt; describe cómo se propagan estas relaciones cuando los tipos se anidan en estructuras (arreglos, objetos) o en firmas de función. Es el motivo por el que, por ejemplo, un arreglo de un subtipo no siempre es intercambiable con un arreglo de su supertipo: la mutabilidad introduce restricciones que el compilador debe respetar para mantener la solidez del sistema.&lt;/p&gt;
&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;El sistema de tipos de TypeScript es una jerarquía gobernada por reglas de subtipado y varianza, con &lt;code&gt;unknown&lt;/code&gt; como tipo superior y &lt;code&gt;never&lt;/code&gt; como tipo inferior. Distinguir &lt;code&gt;null&lt;/code&gt;, &lt;code&gt;undefined&lt;/code&gt;, &lt;code&gt;void&lt;/code&gt; y &lt;code&gt;never&lt;/code&gt;, y comprender cómo &lt;code&gt;B &amp;lt;: A&lt;/code&gt; permite sustituir un tipo por otro, te da una intuición precisa de por qué el compilador acepta o rechaza una asignación.&lt;/p&gt;
&lt;p&gt;En el siguiente artículo aplicaremos metaprogramación con &lt;strong&gt;decoradores&lt;/strong&gt;, funciones que extienden el comportamiento de clases, métodos y propiedades.&lt;/p&gt;</content:encoded></item><item><title>SQL: Subqueries y Tipos de JOIN Avanzados</title><link>https://blog.dacadev.com/programacion/sql/06-subqueries-subconsultas/</link><pubDate>Sat, 20 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/programacion/sql/06-subqueries-subconsultas/</guid><dc:creator>Dacadev</dc:creator><category>programación</category><description>Aprende a usar subqueries en SQL: subconsultas correlacionadas, EXISTS y joins avanzados para consultar datos relacionales con precisión.</description><media:content url="https://blog.dacadev.com/images/programming/sql/subqueries/banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#qué-es-una-subquery-en-sql"&gt;Qué es una subquery en SQL&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#tipos-de-subqueries"&gt;Tipos de subqueries&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#subqueries-no-correlacionadas"&gt;Subqueries no correlacionadas&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#subqueries-de-múltiples-filas-y-una-columna"&gt;Subqueries de múltiples filas y una columna&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#subqueries-multicolumna"&gt;Subqueries multicolumna&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#subqueries-correlacionadas"&gt;Subqueries correlacionadas&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#el-operador-exists"&gt;El operador EXISTS&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#joins-avanzados-revisitando-las-uniones"&gt;JOINs avanzados: revisitando las uniones&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#outer-joins"&gt;Outer joins&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#outer-joins-de-tres-tablas"&gt;Outer joins de tres tablas&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#cross-joins"&gt;Cross joins&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#natural-joins"&gt;Natural joins&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#conclusión"&gt;Conclusión&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;p&gt;Cuando tus consultas SQL empiezan a mezclar filtros, agregaciones y relaciones entre tablas, los &lt;code&gt;JOIN&lt;/code&gt; básicos dejan de ser suficientes para expresar ciertas reglas de negocio con claridad. Las &lt;strong&gt;subqueries&lt;/strong&gt; o &lt;strong&gt;subconsultas en SQL&lt;/strong&gt; permiten encapsular una consulta dentro de otra, reutilizar resultados intermedios y construir filtros más precisos sin mover lógica innecesaria a la aplicación. En el artículo anterior vimos &lt;a href="https://blog.dacadev.com/programacion/sql/05-consultas-multiples-tablas-joins"



 


&gt;consultas a múltiples tablas con JOINs&lt;/a&gt;; ahora vamos a extender esa base con subconsultas, &lt;code&gt;EXISTS&lt;/code&gt; y tipos de &lt;code&gt;JOIN&lt;/code&gt; más avanzados.&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;En este artículo aprenderás a usar subqueries escalares, subconsultas de múltiples filas, subqueries correlacionadas, el operador &lt;code&gt;EXISTS&lt;/code&gt;, &lt;code&gt;LEFT OUTER JOIN&lt;/code&gt;, &lt;code&gt;CROSS JOIN&lt;/code&gt; y &lt;code&gt;NATURAL JOIN&lt;/code&gt;.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="qué-es-una-subquery-en-sql"&gt;Qué es una subquery en SQL&lt;/h2&gt;
&lt;p&gt;Una &lt;strong&gt;subquery&lt;/strong&gt; es una consulta contenida dentro de otra sentencia SQL. A la sentencia externa la llamaremos &lt;strong&gt;consulta contenedora&lt;/strong&gt; o consulta principal. La subquery siempre va entre paréntesis y, en muchos motores, se evalúa antes de que la consulta principal termine de resolver su filtro o su conjunto de datos.&lt;/p&gt;
&lt;p&gt;Como cualquier consulta, una subquery puede retornar diferentes formas de resultado:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Una sola fila con una sola columna.&lt;/li&gt;
&lt;li&gt;Múltiples filas con una sola columna.&lt;/li&gt;
&lt;li&gt;Múltiples filas con múltiples columnas.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Analicemos un primer ejemplo. Queremos obtener el cliente con el &lt;code&gt;customer_id&lt;/code&gt; más alto:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; (&lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;MAX&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt;) &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+------------+-----------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+------------+-----------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;599&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;AUSTIN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CINTRON&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+------------+-----------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#c678dd"&gt;row&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;27&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La subquery &lt;code&gt;(SELECT MAX(customer_id) FROM customer)&lt;/code&gt; retorna un único valor. Por eso podemos compararla con &lt;code&gt;=&lt;/code&gt; en el &lt;code&gt;WHERE&lt;/code&gt; de la consulta principal.&lt;/p&gt;




 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Cuando una subquery retorna una fila y una sola columna, se comporta como una &lt;strong&gt;subquery escalar&lt;/strong&gt;. Puedes usarla con operadores como &lt;code&gt;=&lt;/code&gt;, &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;, &lt;code&gt;!=&lt;/code&gt;, &lt;code&gt;&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;gt;=&lt;/code&gt;, &lt;code&gt;&amp;lt;&lt;/code&gt; y &lt;code&gt;&amp;lt;=&lt;/code&gt;.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="tipos-de-subqueries"&gt;Tipos de subqueries&lt;/h2&gt;
&lt;p&gt;No todas las subconsultas tienen el mismo comportamiento. La diferencia más importante está en si la subquery depende o no de la consulta principal.&lt;/p&gt;
&lt;h3 id="subqueries-no-correlacionadas"&gt;Subqueries no correlacionadas&lt;/h3&gt;
&lt;p&gt;Las &lt;strong&gt;subqueries no correlacionadas&lt;/strong&gt; no dependen directamente de la consulta contenedora. Puedes ejecutarlas por separado, inspeccionar su resultado y luego entender cómo ese resultado alimenta el &lt;code&gt;WHERE&lt;/code&gt;, &lt;code&gt;HAVING&lt;/code&gt; o incluso el &lt;code&gt;FROM&lt;/code&gt; de la consulta principal.&lt;/p&gt;
&lt;p&gt;El ejemplo anterior es una subquery no correlacionada. Observemos otro caso: obtener todas las ciudades cuyo país no sea India.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;city_id&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;city&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;city&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;country_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;&amp;lt;&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; (&lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;country_id&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;country&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;country&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;India&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------+----------------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;city_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;city&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------+----------------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;A&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Corua&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;La&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Corua&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Abha&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;3&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Abu&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Dhabi&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;4&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Acua&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;599&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Zhoushan&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;600&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Ziguinchor&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------+----------------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;540&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;02&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Aquí la subquery retorna el &lt;code&gt;country_id&lt;/code&gt; asociado a India. La consulta principal usa ese valor para excluir todas las ciudades que pertenezcan a ese país.&lt;/p&gt;




 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Si usas &lt;code&gt;=&lt;/code&gt; con una subquery que retorna más de un valor, el motor no puede comparar un valor escalar contra un conjunto de filas. En ese caso necesitas operadores como &lt;code&gt;IN&lt;/code&gt;, &lt;code&gt;ANY&lt;/code&gt;, &lt;code&gt;ALL&lt;/code&gt; o reestructurar la consulta.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h3 id="subqueries-de-múltiples-filas-y-una-columna"&gt;Subqueries de múltiples filas y una columna&lt;/h3&gt;
&lt;p&gt;Cuando una subquery retorna varias filas pero una sola columna, &lt;code&gt;IN&lt;/code&gt; suele ser el operador adecuado. Este operador compara el valor del lado izquierdo contra el conjunto de valores retornado por la subquery.&lt;/p&gt;
&lt;p&gt;Consideremos una consulta para obtener ciudades de Canadá o México:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;city_id&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;city&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;city&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;country_id&lt;/span&gt; &lt;span style="color:#c678dd"&gt;IN&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; (&lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;country_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;country&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;country&lt;/span&gt; &lt;span style="color:#c678dd"&gt;IN&lt;/span&gt; (&lt;span style="color:#98c379"&gt;&amp;#39;Canada&amp;#39;&lt;/span&gt;,&lt;span style="color:#98c379"&gt;&amp;#39;Mexico&amp;#39;&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------+----------------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;city_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;city&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------+----------------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;179&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Gatineau&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;196&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Halifax&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;300&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Lethbridge&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;313&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;London&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;556&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Uruapan&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;595&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Zapopan&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------+----------------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;37&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;00&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La subquery retorna los &lt;code&gt;country_id&lt;/code&gt; de ambos países. Luego &lt;code&gt;IN&lt;/code&gt; filtra las ciudades cuyo &lt;code&gt;country_id&lt;/code&gt; esté dentro de ese conjunto.&lt;/p&gt;
&lt;h3 id="subqueries-multicolumna"&gt;Subqueries multicolumna&lt;/h3&gt;
&lt;p&gt;Las &lt;strong&gt;subqueries multicolumna&lt;/strong&gt; retornan más de una columna y son útiles cuando necesitas comparar combinaciones de valores o enriquecer la lógica de selección. En SQL también es común resolver este tipo de necesidad con varias subqueries coordinadas, especialmente cuando cada filtro opera sobre una dimensión diferente.&lt;/p&gt;
&lt;p&gt;Observemos este caso: queremos encontrar pares &lt;code&gt;actor_id&lt;/code&gt; y &lt;code&gt;film_id&lt;/code&gt; donde el actor tenga apellido &lt;code&gt;MONROE&lt;/code&gt; y la película tenga clasificación &lt;code&gt;PG&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fa&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;actor_id&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;fa&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film_actor&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fa&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fa&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;actor_id&lt;/span&gt; &lt;span style="color:#c678dd"&gt;IN&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; (&lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;actor_id&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;actor&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;MONROE&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;AND&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fa&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt; &lt;span style="color:#c678dd"&gt;IN&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; (&lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rating&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;PG&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;----------+---------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;actor_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;----------+---------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;120&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;63&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;120&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;144&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;120&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;414&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;178&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;983&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;----------+---------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;11&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;00&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Esta consulta combina dos filtros independientes: uno sobre actores y otro sobre películas. El resultado final sale de la tabla intermedia &lt;code&gt;film_actor&lt;/code&gt;, que representa la relación muchos-a-muchos.&lt;/p&gt;
&lt;h2 id="subqueries-correlacionadas"&gt;Subqueries correlacionadas&lt;/h2&gt;
&lt;p&gt;Hasta ahora, las subqueries han sido independientes. Una &lt;strong&gt;subquery correlacionada&lt;/strong&gt;, en cambio, depende de la consulta principal porque referencia una o más columnas de la fila que se está evaluando afuera.&lt;/p&gt;
&lt;p&gt;Esto cambia el modelo mental: la subquery no se ejecuta una sola vez para producir un conjunto estático, sino que puede evaluarse por cada fila candidata de la consulta externa. Por eso conviene revisar su costo, especialmente en tablas grandes.&lt;/p&gt;
&lt;p&gt;Analicemos una consulta que obtiene clientes con exactamente 20 rentas:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;, &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#d19a66"&gt;20&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; (&lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;count&lt;/span&gt;(&lt;span style="color:#56b6c2"&gt;*&lt;/span&gt;) &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental&lt;/span&gt; &lt;span style="color:#e06c75"&gt;r&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;r&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------------+-------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------------+-------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;LAUREN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;HUDSON&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JEANETTE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;GREENE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;TARA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;RYAN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;WILMA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;RICHARDS&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ALFREDO&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;MCADAMS&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------------+-------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;15&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;01&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La parte clave es &lt;code&gt;r.customer_id = c.customer_id&lt;/code&gt;. La subquery necesita el &lt;code&gt;customer_id&lt;/code&gt; de la fila actual de &lt;code&gt;customer&lt;/code&gt;, por eso está correlacionada.&lt;/p&gt;
&lt;h3 id="el-operador-exists"&gt;El operador EXISTS&lt;/h3&gt;
&lt;p&gt;El operador &lt;code&gt;EXISTS&lt;/code&gt; valida si la subquery retorna al menos una fila. No importa qué columnas seleccione la subquery; lo relevante es la existencia de registros que cumplan la condición.&lt;/p&gt;
&lt;p&gt;Por convención, muchas consultas usan &lt;code&gt;SELECT 1&lt;/code&gt; dentro de &lt;code&gt;EXISTS&lt;/code&gt; para indicar que el valor retornado no es importante:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;, &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#c678dd"&gt;EXISTS&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; (&lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental&lt;/span&gt; &lt;span style="color:#e06c75"&gt;r&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;r&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;AND&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;date&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;r&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;rental_date&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;2005-05-25&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------------+-------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------------+-------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CHARLOTTE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;HUNTER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DELORES&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;HANSEN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;MINNIE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ROMERO&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;NELSON&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CHRISTENSON&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------------+-------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;8&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;03&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;EXISTS&lt;/code&gt; es especialmente expresivo cuando la pregunta de negocio es binaria: “incluye esta fila si existe al menos una relación que cumple la condición”.&lt;/p&gt;




 
 





 


&lt;div class="notice tip"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z" /&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Tip&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Usa &lt;code&gt;EXISTS&lt;/code&gt; cuando quieras comprobar existencia y &lt;code&gt;IN&lt;/code&gt; cuando quieras comparar contra un conjunto concreto de valores. Ambos pueden ser optimizados por el motor, pero expresan intenciones distintas.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="joins-avanzados-revisitando-las-uniones"&gt;JOINs avanzados: revisitando las uniones&lt;/h2&gt;
&lt;p&gt;Hasta este punto de la serie hemos trabajado principalmente con &lt;code&gt;INNER JOIN&lt;/code&gt;. Ese tipo de unión retorna únicamente las filas que cumplen la condición en ambas tablas. Sin embargo, SQL ofrece variantes útiles para preservar filas sin coincidencias, generar combinaciones cartesianas o delegar la condición de unión al motor.&lt;/p&gt;
&lt;h2 id="outer-joins"&gt;Outer joins&lt;/h2&gt;
&lt;p&gt;Los &lt;strong&gt;outer joins&lt;/strong&gt; retornan las filas que cumplen la condición de unión y, además, conservan filas de una tabla aunque no tengan coincidencias del otro lado. En un &lt;code&gt;LEFT OUTER JOIN&lt;/code&gt;, se preservan todas las filas de la tabla de la izquierda.&lt;/p&gt;
&lt;p&gt;Observemos un conteo de copias por película:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;title&lt;/span&gt;, &lt;span style="color:#c678dd"&gt;count&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;i&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;inventory_id&lt;/span&gt;) &lt;span style="color:#e06c75"&gt;num_copies&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;LEFT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;OUTER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;inventory&lt;/span&gt; &lt;span style="color:#e06c75"&gt;i&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;i&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;GROUP&lt;/span&gt; &lt;span style="color:#c678dd"&gt;BY&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;title&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------+-----------------------------+------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;title&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;num_copies&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------+-----------------------------+------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ACADEMY&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DINOSAUR&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;8&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ACE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;GOLDFINGER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;3&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;3&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ADAPTATION&lt;/span&gt; &lt;span style="color:#e06c75"&gt;HOLES&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;4&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;4&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;AFFAIR&lt;/span&gt; &lt;span style="color:#e06c75"&gt;PREJUDICE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;7&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;14&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ALICE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FANTASIA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;999&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ZOOLANDER&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FICTION&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;5&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1000&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ZORRO&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ARK&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;8&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------+-----------------------------+------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;1000&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;01&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;ALICE FANTASIA&lt;/code&gt; aparece con &lt;code&gt;0&lt;/code&gt; copias porque no tiene registros asociados en &lt;code&gt;inventory&lt;/code&gt;. Aun así, el &lt;code&gt;LEFT OUTER JOIN&lt;/code&gt; conserva la película porque &lt;code&gt;film&lt;/code&gt; está a la izquierda.&lt;/p&gt;
&lt;p&gt;Veamos la misma situación sin agregación:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;title&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;i&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;inventory_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;LEFT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;OUTER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;inventory&lt;/span&gt; &lt;span style="color:#e06c75"&gt;i&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;i&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt; &lt;span style="color:#c678dd"&gt;BETWEEN&lt;/span&gt; &lt;span style="color:#d19a66"&gt;13&lt;/span&gt; &lt;span style="color:#c678dd"&gt;AND&lt;/span&gt; &lt;span style="color:#d19a66"&gt;15&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------+----------------+--------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;title&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;inventory_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------+----------------+--------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;13&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ALI&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FOREVER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;67&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;13&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ALI&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FOREVER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;68&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;13&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ALI&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FOREVER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;69&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;13&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ALI&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FOREVER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;70&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;14&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ALICE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FANTASIA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NULL&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;15&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ALIEN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CENTER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;71&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;15&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ALIEN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CENTER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;72&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;15&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ALIEN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CENTER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;73&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;15&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ALIEN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CENTER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;74&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;15&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ALIEN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CENTER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;75&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;15&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ALIEN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CENTER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;76&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------+----------------+--------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;11&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;00&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El &lt;code&gt;NULL&lt;/code&gt; en &lt;code&gt;inventory_id&lt;/code&gt; indica que no existe fila relacionada en la tabla derecha.&lt;/p&gt;
&lt;h3 id="outer-joins-de-tres-tablas"&gt;Outer joins de tres tablas&lt;/h3&gt;
&lt;p&gt;Puedes encadenar &lt;code&gt;OUTER JOIN&lt;/code&gt; para preservar filas a través de varias relaciones. En este tipo de consulta, el orden importa porque define qué conjunto de filas se conserva en cada paso.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;title&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;i&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;inventory_id&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;r&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;rental_date&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;LEFT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;OUTER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;inventory&lt;/span&gt; &lt;span style="color:#e06c75"&gt;i&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;i&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;LEFT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;OUTER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental&lt;/span&gt; &lt;span style="color:#e06c75"&gt;r&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#e06c75"&gt;i&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;inventory_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;r&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;inventory_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt; &lt;span style="color:#c678dd"&gt;BETWEEN&lt;/span&gt; &lt;span style="color:#d19a66"&gt;13&lt;/span&gt; &lt;span style="color:#c678dd"&gt;AND&lt;/span&gt; &lt;span style="color:#d19a66"&gt;15&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------+----------------+--------------+---------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;title&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;inventory_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental_date&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------+----------------+--------------+---------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;13&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ALI&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FOREVER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;67&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2005&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;07&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;31&lt;/span&gt; &lt;span style="color:#d19a66"&gt;18&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;11&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;17&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;13&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ALI&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FOREVER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;67&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2005&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;08&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;22&lt;/span&gt; &lt;span style="color:#d19a66"&gt;21&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;59&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;29&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;13&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ALI&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FOREVER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;68&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2005&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;07&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;28&lt;/span&gt; &lt;span style="color:#d19a66"&gt;15&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;26&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;20&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;14&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ALICE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FANTASIA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NULL&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NULL&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;15&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ALIEN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CENTER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;71&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2005&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;05&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;28&lt;/span&gt; &lt;span style="color:#d19a66"&gt;02&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;06&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;37&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;15&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ALIEN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CENTER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;76&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2005&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;08&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;17&lt;/span&gt; &lt;span style="color:#d19a66"&gt;07&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;26&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;47&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------+----------------+--------------+---------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;32&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;01&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



 
 





 


&lt;div class="notice tip"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z" /&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Tip&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Aunque existe &lt;code&gt;RIGHT OUTER JOIN&lt;/code&gt;, en muchos equipos se prefiere estandarizar en &lt;code&gt;LEFT OUTER JOIN&lt;/code&gt;. Mantiene la lectura de izquierda a derecha y reduce cambios mentales al revisar consultas complejas.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="cross-joins"&gt;Cross joins&lt;/h2&gt;
&lt;p&gt;Un &lt;code&gt;CROSS JOIN&lt;/code&gt; produce un producto cartesiano: combina cada fila de la primera tabla con cada fila de la segunda. Es útil para generar matrices de combinaciones, calendarios, catálogos base o escenarios de prueba, pero puede crecer muy rápido.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;name&lt;/span&gt; &lt;span style="color:#e06c75"&gt;category_name&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;l&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;name&lt;/span&gt; &lt;span style="color:#e06c75"&gt;language_name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;category&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;CROSS&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#c678dd"&gt;language&lt;/span&gt; &lt;span style="color:#e06c75"&gt;l&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------------+---------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;category_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;language_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------------+---------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Action&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;English&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Action&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Italian&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Action&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Japanese&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Travel&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;English&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Travel&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;German&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------------+---------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;96&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;00&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Si &lt;code&gt;category&lt;/code&gt; tiene 16 filas y &lt;code&gt;language&lt;/code&gt; tiene 6, el resultado tendrá 96 filas. Esa multiplicación es exactamente el comportamiento esperado.&lt;/p&gt;
&lt;h2 id="natural-joins"&gt;Natural joins&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;NATURAL JOIN&lt;/code&gt; deja que el motor determine las columnas de unión usando columnas con el mismo nombre en ambas tablas. Es importante conocerlo, pero no suele ser buena práctica en consultas de producción porque oculta la condición real del &lt;code&gt;JOIN&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;El siguiente ejemplo no retorna filas:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;, &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;date&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;r&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;rental_date&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NATURAL&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental&lt;/span&gt; &lt;span style="color:#e06c75"&gt;r&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;Empty&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;04&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El problema es que &lt;code&gt;customer&lt;/code&gt; y &lt;code&gt;rental&lt;/code&gt; pueden compartir más columnas de las que realmente queremos usar como condición natural. Al proyectar únicamente las columnas necesarias desde &lt;code&gt;customer&lt;/code&gt;, el &lt;code&gt;NATURAL JOIN&lt;/code&gt; puede comportarse como esperamos:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;cust&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;cust&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;date&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;r&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;rental_date&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; (&lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; ) &lt;span style="color:#e06c75"&gt;cust&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NATURAL&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental&lt;/span&gt; &lt;span style="color:#e06c75"&gt;r&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------------+-----------+---------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;date&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;r&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;rental_date&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------------+-----------+---------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;MARY&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SMITH&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2005&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;05&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;25&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;MARY&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SMITH&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2005&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;05&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;28&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;MARY&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SMITH&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2005&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;06&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;15&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;AUSTIN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CINTRON&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2005&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;08&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;23&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------------+-----------+---------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;16044&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;03&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Prefiere &lt;code&gt;JOIN ... ON ...&lt;/code&gt; cuando la consulta debe ser mantenible. La condición explícita documenta la intención y evita cambios inesperados si el esquema gana nuevas columnas con nombres compartidos.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;Las subqueries en SQL te permiten expresar reglas de negocio que dependen de resultados intermedios sin salir del motor de base de datos. Las subconsultas no correlacionadas son ideales para filtros basados en conjuntos estáticos; las correlacionadas son útiles cuando cada fila externa necesita una evaluación específica; y &lt;code&gt;EXISTS&lt;/code&gt; comunica con claridad validaciones de existencia.&lt;/p&gt;
&lt;p&gt;En el lado de los &lt;code&gt;JOIN&lt;/code&gt;, &lt;code&gt;LEFT OUTER JOIN&lt;/code&gt; conserva filas sin coincidencias, &lt;code&gt;CROSS JOIN&lt;/code&gt; genera combinaciones cartesianas y &lt;code&gt;NATURAL JOIN&lt;/code&gt; delega la condición al motor, aunque conviene usarlo con cuidado. La clave es elegir la herramienta que haga más explícita la intención de la consulta.&lt;/p&gt;
&lt;p&gt;En el siguiente artículo de la serie vamos a trabajar con &lt;a href="https://blog.dacadev.com/programacion/sql/07-vistas-views"



 


&gt;&lt;strong&gt;Vistas (Views)&lt;/strong&gt;&lt;/a&gt;, una forma práctica de encapsular consultas y exponer modelos de lectura reutilizables dentro de la base de datos.&lt;/p&gt;</content:encoded></item><item><title>TypeScript: Genéricos y código reutilizable</title><link>https://blog.dacadev.com/typescript/genericos/</link><pubDate>Sat, 20 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/typescript/genericos/</guid><dc:creator>Dacadev</dc:creator><category>programación</category><description>Aprende a usar genéricos en TypeScript para escribir funciones y clases reutilizables que preservan la seguridad de tipos con parámetros de tipo dinámicos.</description><media:content url="https://blog.dacadev.com/images/typescript/generics/banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#funciones-genéricas"&gt;Funciones genéricas&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#por-qué-no-basta-con-any"&gt;Por qué no basta con any&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#clases-genéricas"&gt;Clases genéricas&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#restringir-genéricos-con-extends"&gt;Restringir genéricos con extends&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#conclusión"&gt;Conclusión&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;





 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Séptimo artículo de la serie sobre &lt;strong&gt;TypeScript&lt;/strong&gt;. Exploraremos los genéricos: funciones y clases que operan sobre tipos dinámicos sin renunciar a la verificación estática.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Los &lt;strong&gt;genéricos en TypeScript&lt;/strong&gt; resuelven una tensión recurrente: escribir código reutilizable que funcione con cualquier tipo, pero sin caer en &lt;code&gt;any&lt;/code&gt; y perder toda la seguridad. Un genérico introduce un &lt;em&gt;parámetro de tipo&lt;/em&gt; —una variable que representa un tipo aún por determinar— que se resuelve en el momento de uso. Analicemos cómo aplicarlos.&lt;/p&gt;
&lt;h2 id="funciones-genéricas"&gt;Funciones genéricas&lt;/h2&gt;
&lt;p&gt;Una función genérica declara su parámetro de tipo con la sintaxis &lt;code&gt;&amp;lt;T&amp;gt;&lt;/code&gt; antes de la lista de parámetros. &lt;code&gt;T&lt;/code&gt; representa el tipo que recibirá, y la función puede usarlo para tipar argumentos y retorno:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// Función tradicional
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;export&lt;/span&gt; &lt;span style="color:#c678dd"&gt;function&lt;/span&gt; &lt;span style="color:#e06c75"&gt;genericFunction&lt;/span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;T&lt;/span&gt;&amp;gt;(&lt;span style="color:#e06c75"&gt;argumento&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;T&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e06c75"&gt;T&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;argumento&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// Arrow function
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;export&lt;/span&gt; &lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;genericArrowFunction&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &amp;lt;&lt;span style="color:#e06c75"&gt;T&lt;/span&gt;&amp;gt;(&lt;span style="color:#e06c75"&gt;argumento&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;T&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e06c75"&gt;T&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;argumento&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La función anterior retorna exactamente el mismo tipo que recibe. Si la invocas con un &lt;code&gt;string&lt;/code&gt;, TypeScript sabe que el retorno es &lt;code&gt;string&lt;/code&gt;; si la invocas con un &lt;code&gt;number&lt;/code&gt;, el retorno es &lt;code&gt;number&lt;/code&gt;. Esto es lo que distingue a un genérico de &lt;code&gt;any&lt;/code&gt;: &lt;strong&gt;la relación entre entrada y salida se preserva&lt;/strong&gt;.&lt;/p&gt;




 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;&lt;code&gt;T&lt;/code&gt; es el nombre convencional, pero es arbitrario. Para múltiples parámetros suelen usarse &lt;code&gt;T&lt;/code&gt;, &lt;code&gt;U&lt;/code&gt;, &lt;code&gt;K&lt;/code&gt;, &lt;code&gt;V&lt;/code&gt;, o nombres descriptivos como &lt;code&gt;TItem&lt;/code&gt; cuando aportan claridad.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="por-qué-no-basta-con-any"&gt;Por qué no basta con any&lt;/h2&gt;
&lt;p&gt;Comparemos las dos aproximaciones para entender el valor de los genéricos:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// Con any: se pierde la información de tipo
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;function&lt;/span&gt; &lt;span style="color:#e06c75"&gt;identityAny&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;arg&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;any&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;any&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;arg&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;identityAny&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;hola&amp;#39;&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;// a es any → sin autocompletado ni verificación
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// Con genéricos: el tipo se conserva
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;function&lt;/span&gt; &lt;span style="color:#e06c75"&gt;identity&lt;/span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;T&lt;/span&gt;&amp;gt;(&lt;span style="color:#e06c75"&gt;arg&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;T&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e06c75"&gt;T&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;arg&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;b&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;identity&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;hola&amp;#39;&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;// b es string → seguridad completa
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Con &lt;code&gt;any&lt;/code&gt;, el resultado pierde todo su tipo y el typechecker deja de ayudar. Con un genérico, la firma encadena el tipo de entrada con el de salida.&lt;/p&gt;
&lt;h2 id="clases-genéricas"&gt;Clases genéricas&lt;/h2&gt;
&lt;p&gt;Las clases también admiten parámetros de tipo, lo que permite construir estructuras de datos reutilizables y type-safe. El parámetro se declara junto al nombre de la clase y queda disponible en todos sus miembros:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e06c75"&gt;MyMap&lt;/span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;K&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;V&lt;/span&gt;&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;constructor&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;initialKey&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;K&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;initialValue&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;V&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#7f848e"&gt;// ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;get&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;key&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;K&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e06c75"&gt;V&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#7f848e"&gt;// ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;key&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;K&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;value&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;V&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#c678dd"&gt;void&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#7f848e"&gt;// ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;static&lt;/span&gt; &lt;span style="color:#c678dd"&gt;of&lt;/span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;K&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;V&lt;/span&gt;&amp;gt;(&lt;span style="color:#e06c75"&gt;k&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;K&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;v&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;V&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e06c75"&gt;MyMap&lt;/span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;K&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;V&lt;/span&gt;&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#7f848e"&gt;// ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Al instanciarla, los tipos pueden indicarse explícitamente o inferirse de los argumentos:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#c678dd"&gt;new&lt;/span&gt; &lt;span style="color:#e06c75"&gt;MyMap&lt;/span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;string&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;number&lt;/span&gt;&amp;gt;(&lt;span style="color:#98c379"&gt;&amp;#39;k&amp;#39;&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;// MyMap&amp;lt;string, number&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;b&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#c678dd"&gt;new&lt;/span&gt; &lt;span style="color:#e06c75"&gt;MyMap&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;k&amp;#39;&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;true&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;// MyMap&amp;lt;string, boolean&amp;gt; (inferido)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#c678dd"&gt;get&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;k&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;b&lt;/span&gt;.&lt;span style="color:#c678dd"&gt;set&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;k&amp;#39;&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;false&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre class="mermaid"&gt;flowchart LR
 G[&amp;#34;MyMap&amp;amp;lt;K, V&amp;amp;gt;&amp;#34;] --&amp;gt; A[&amp;#34;MyMap&amp;amp;lt;string, number&amp;amp;gt;&amp;#34;]
 G --&amp;gt; B[&amp;#34;MyMap&amp;amp;lt;string, boolean&amp;amp;gt;&amp;#34;]
 G --&amp;gt; C[&amp;#34;MyMap&amp;amp;lt;number, Hero&amp;amp;gt;&amp;#34;]
&lt;/pre&gt;

&lt;p&gt;Una sola definición genérica genera tantas variantes type-safe como combinaciones de tipos uses.&lt;/p&gt;
&lt;h2 id="restringir-genéricos-con-extends"&gt;Restringir genéricos con extends&lt;/h2&gt;
&lt;p&gt;A veces un genérico no debe aceptar cualquier tipo, sino solo aquellos que cumplan cierta forma. La cláusula &lt;code&gt;extends&lt;/code&gt; impone esa restricción y, a la vez, habilita el acceso seguro a los miembros garantizados:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;function&lt;/span&gt; &lt;span style="color:#e06c75"&gt;getLength&lt;/span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;T&lt;/span&gt; &lt;span style="color:#e06c75"&gt;extends&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;length&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;number&lt;/span&gt; }&amp;gt;(&lt;span style="color:#e06c75"&gt;item&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;T&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;item&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;length&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;getLength&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;hola&amp;#39;&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;// OK: string tiene length
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;getLength&lt;/span&gt;([&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;2&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;]) &lt;span style="color:#7f848e"&gt;// OK: array tiene length
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;getLength&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;42&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;// Error: number no tiene &amp;#39;length&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;T extends { length: number }&lt;/code&gt; restringe &lt;code&gt;T&lt;/code&gt; a tipos que posean una propiedad &lt;code&gt;length&lt;/code&gt;, permitiendo usarla con seguridad dentro de la función.&lt;/p&gt;
&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;Los genéricos son la herramienta que permite escribir código verdaderamente reutilizable sin sacrificar la verificación de tipos. Las funciones genéricas encadenan el tipo de entrada con el de salida, las clases genéricas habilitan estructuras de datos type-safe, y las restricciones con &lt;code&gt;extends&lt;/code&gt; acotan los tipos aceptados mientras exponen sus miembros de forma segura.&lt;/p&gt;
&lt;p&gt;En el próximo artículo abordaremos los &lt;strong&gt;tipos avanzados&lt;/strong&gt;: subtipos, supertipos, varianza y la jerarquía completa del sistema de tipos.&lt;/p&gt;</content:encoded></item><item><title>TypeScript: Clases, herencia y patrones de diseño</title><link>https://blog.dacadev.com/typescript/clases-e-interfaces/</link><pubDate>Fri, 19 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/typescript/clases-e-interfaces/</guid><dc:creator>Dacadev</dc:creator><category>programación</category><description>Domina las clases en TypeScript: herencia, modificadores public/protected/private, clases abstractas, getters/setters, estáticos y patrones Factory y Builder.</description><media:content url="https://blog.dacadev.com/images/typescript/classes-inheritance/banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#clases-y-herencia"&gt;Clases y herencia&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#modificadores-de-acceso"&gt;Modificadores de acceso&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#clases-abstractas"&gt;Clases abstractas&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#super-invocar-a-la-clase-padre"&gt;super: invocar a la clase padre&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#getters-y-setters"&gt;Getters y setters&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#miembros-estáticos"&gt;Miembros estáticos&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#this-como-tipo-de-retorno"&gt;this como tipo de retorno&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#tipado-estructural"&gt;Tipado estructural&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#constructor-privado"&gt;Constructor privado&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#patrones-de-diseño-habilitados"&gt;Patrones de diseño habilitados&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#factory-pattern"&gt;Factory Pattern&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#builder-pattern"&gt;Builder Pattern&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#conclusión"&gt;Conclusión&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;





 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Sexto artículo de la serie sobre &lt;strong&gt;TypeScript&lt;/strong&gt;. Recorreremos las clases: herencia, modificadores de acceso, clases abstractas, &lt;code&gt;super&lt;/code&gt;, getters/setters, miembros estáticos, tipado estructural y los patrones de diseño que habilitan.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Las &lt;strong&gt;clases en TypeScript&lt;/strong&gt; parten de la sintaxis de JavaScript y la enriquecen con modificadores de acceso, clases abstractas y tipado estructural. El resultado es un modelo de orientación a objetos cercano al de lenguajes como C++ o Java, pero que compila a JavaScript estándar. Analicemos sus capacidades.&lt;/p&gt;
&lt;h2 id="clases-y-herencia"&gt;Clases y herencia&lt;/h2&gt;
&lt;p&gt;La declaración usa &lt;code&gt;class&lt;/code&gt; y la herencia se establece con &lt;code&gt;extends&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Piece&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e06c75"&gt;King&lt;/span&gt; &lt;span style="color:#c678dd"&gt;extends&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Piece&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Queen&lt;/span&gt; &lt;span style="color:#c678dd"&gt;extends&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Piece&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Bishop&lt;/span&gt; &lt;span style="color:#c678dd"&gt;extends&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Piece&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Podemos restringir los atributos a valores concretos combinando clases con tipos literales:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;type&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Color&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Black&amp;#39;&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;White&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;type&lt;/span&gt; &lt;span style="color:#e06c75"&gt;File&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;A&amp;#39;&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;B&amp;#39;&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;C&amp;#39;&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;D&amp;#39;&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;E&amp;#39;&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;F&amp;#39;&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;G&amp;#39;&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;H&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;type&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Rank&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;3&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;4&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;5&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;6&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;7&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;8&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Position&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;constructor&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;private&lt;/span&gt; &lt;span style="color:#e06c75"&gt;file&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;File&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;private&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rank&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;Rank&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ) {}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Declarar los parámetros del constructor con un modificador (&lt;code&gt;private file: File&lt;/code&gt;) es un atajo: TypeScript crea y asigna la propiedad automáticamente, evitando el habitual &lt;code&gt;this.file = file&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="modificadores-de-acceso"&gt;Modificadores de acceso&lt;/h2&gt;
&lt;p&gt;TypeScript define tres niveles de visibilidad para atributos y métodos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;public&lt;/code&gt;: accesible desde cualquier lugar. Es el nivel por defecto.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;protected&lt;/code&gt;: accesible desde la propia clase y sus subclases.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;private&lt;/code&gt;: accesible únicamente desde la propia clase.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Avenger&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;constructor&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;private&lt;/span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;public&lt;/span&gt; &lt;span style="color:#e06c75"&gt;team&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;public&lt;/span&gt; &lt;span style="color:#e06c75"&gt;realName?&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ) {}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;public&lt;/span&gt; &lt;span style="color:#e06c75"&gt;bio() {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#98c379"&gt;`&lt;/span&gt;&lt;span style="color:#98c379"&gt;${&lt;/span&gt;&lt;span style="color:#c678dd"&gt;this&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;name&lt;/span&gt;&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt; &lt;/span&gt;&lt;span style="color:#98c379"&gt;${&lt;/span&gt;&lt;span style="color:#c678dd"&gt;this&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;team&lt;/span&gt;&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;private&lt;/span&gt; &lt;span style="color:#e06c75"&gt;bioInterno() {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#98c379"&gt;`&lt;/span&gt;&lt;span style="color:#98c379"&gt;${&lt;/span&gt;&lt;span style="color:#c678dd"&gt;this&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;realName&lt;/span&gt;&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt; &lt;/span&gt;&lt;span style="color:#98c379"&gt;${&lt;/span&gt;&lt;span style="color:#c678dd"&gt;this&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;team&lt;/span&gt;&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;&lt;code&gt;private&lt;/code&gt; y &lt;code&gt;protected&lt;/code&gt; solo aplican en tiempo de compilación. El JavaScript emitido no impide el acceso en runtime; para privacidad real en ejecución usa los campos privados nativos de JavaScript (&lt;code&gt;#campo&lt;/code&gt;).&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="clases-abstractas"&gt;Clases abstractas&lt;/h2&gt;
&lt;p&gt;Una clase &lt;code&gt;abstract&lt;/code&gt; define una plantilla que no puede instanciarse, pero sirve de esqueleto para sus subclases. Puede declarar miembros concretos y miembros &lt;code&gt;abstract&lt;/code&gt; que las subclases están obligadas a implementar:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;abstract&lt;/span&gt; &lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Mutante&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;constructor&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;public&lt;/span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;public&lt;/span&gt; &lt;span style="color:#e06c75"&gt;realName&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ) {}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Xmen&lt;/span&gt; &lt;span style="color:#c678dd"&gt;extends&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Mutante&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;public&lt;/span&gt; &lt;span style="color:#e06c75"&gt;saveWorld() {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Mundo salvado&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Villano&lt;/span&gt; &lt;span style="color:#c678dd"&gt;extends&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Mutante&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;public&lt;/span&gt; &lt;span style="color:#e06c75"&gt;conquistWorld() {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Mundo conquistado&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;wolverine&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#c678dd"&gt;new&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Xmen&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;Wolverine&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;Logan&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;magneto&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#c678dd"&gt;new&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Villano&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;Magneto&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;Magnus&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Una ventaja adicional: una función puede aceptar cualquier objeto que herede de la clase abstracta, lo que habilita el polimorfismo:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;printName&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;character&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;Mutante&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;character&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;name&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;printName&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;wolverine&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;printName&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;magneto&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="super-invocar-a-la-clase-padre"&gt;super: invocar a la clase padre&lt;/h2&gt;
&lt;p&gt;Cuando una subclase sobrescribe un método del padre, puede invocar la versión original con &lt;code&gt;super.metodo()&lt;/code&gt;. Si la subclase define un constructor, &lt;strong&gt;debe&lt;/strong&gt; llamar a &lt;code&gt;super()&lt;/code&gt; para inicializar correctamente la cadena de herencia:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Xmen&lt;/span&gt; &lt;span style="color:#c678dd"&gt;extends&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Avenger&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;constructor&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;realName&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;, &lt;span style="color:#c678dd"&gt;public&lt;/span&gt; &lt;span style="color:#e06c75"&gt;isMutant&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;boolean&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;super&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;name&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;realName&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;public&lt;/span&gt; &lt;span style="color:#e06c75"&gt;getFullNameDesdeXmen() {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#c678dd"&gt;super&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;getFullName&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="getters-y-setters"&gt;Getters y setters&lt;/h2&gt;
&lt;p&gt;Los &lt;em&gt;accessors&lt;/em&gt; exponen métodos que se comportan sintácticamente como atributos, facilitando la lectura y asignación controladas:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Xmen&lt;/span&gt; &lt;span style="color:#c678dd"&gt;extends&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Avenger&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;get&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fullName() {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#98c379"&gt;`&lt;/span&gt;&lt;span style="color:#98c379"&gt;${&lt;/span&gt;&lt;span style="color:#c678dd"&gt;this&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;name&lt;/span&gt;&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt; - &lt;/span&gt;&lt;span style="color:#98c379"&gt;${&lt;/span&gt;&lt;span style="color:#c678dd"&gt;this&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;realName&lt;/span&gt;&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fullName&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;this&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;realName&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;wolverine&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#c678dd"&gt;new&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Xmen&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;Wolverine&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;Logan&amp;#39;&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;true&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;wolverine&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;fullName&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;// se lee como atributo
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;wolverine&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;fullName&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;David&amp;#39;&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// se asigna como atributo
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="miembros-estáticos"&gt;Miembros estáticos&lt;/h2&gt;
&lt;p&gt;Los miembros &lt;code&gt;static&lt;/code&gt; pertenecen a la clase, no a sus instancias:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Avenger&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;static&lt;/span&gt; &lt;span style="color:#e06c75"&gt;avgAge&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;35&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;static&lt;/span&gt; &lt;span style="color:#e06c75"&gt;getAvgAge() {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Avenger&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;avgAge&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;Avenger&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;avgAge&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;// se accede vía la clase
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="this-como-tipo-de-retorno"&gt;this como tipo de retorno&lt;/h2&gt;
&lt;p&gt;Cuando un método retorna la propia instancia, su tipo de retorno es &lt;code&gt;this&lt;/code&gt;. Esto es la base del encadenamiento de métodos (&lt;em&gt;method chaining&lt;/em&gt;):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Set&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;add&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;value&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#c678dd"&gt;this&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#7f848e"&gt;// ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#c678dd"&gt;this&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="tipado-estructural"&gt;Tipado estructural&lt;/h2&gt;
&lt;p&gt;TypeScript verifica las clases por &lt;strong&gt;estructura&lt;/strong&gt;, no por nombre. Dos tipos compatibles en forma son intercambiables, con una salvedad: los miembros &lt;code&gt;private&lt;/code&gt; rompen la compatibilidad estructural:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e06c75"&gt;A&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;private&lt;/span&gt; &lt;span style="color:#e06c75"&gt;x&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e06c75"&gt;B&lt;/span&gt; &lt;span style="color:#c678dd"&gt;extends&lt;/span&gt; &lt;span style="color:#e06c75"&gt;A&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;function&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;a&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;A&lt;/span&gt;) {}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;f&lt;/span&gt;(&lt;span style="color:#c678dd"&gt;new&lt;/span&gt; &lt;span style="color:#e06c75"&gt;A&lt;/span&gt;()) &lt;span style="color:#7f848e"&gt;// OK
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;f&lt;/span&gt;(&lt;span style="color:#c678dd"&gt;new&lt;/span&gt; &lt;span style="color:#e06c75"&gt;B&lt;/span&gt;()) &lt;span style="color:#7f848e"&gt;// OK
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;f&lt;/span&gt;({ &lt;span style="color:#e06c75"&gt;x&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;1&lt;/span&gt; }) &lt;span style="color:#7f848e"&gt;// Error TS2345: &amp;#39;x&amp;#39; es private en &amp;#39;A&amp;#39; pero no en &amp;#39;{x: number}&amp;#39;.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="constructor-privado"&gt;Constructor privado&lt;/h2&gt;
&lt;p&gt;Un constructor &lt;code&gt;private&lt;/code&gt; impide instanciar la clase desde fuera, lo que permite controlar su creación. Es la base del patrón &lt;em&gt;singleton&lt;/em&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Apocalipsis&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;private&lt;/span&gt; &lt;span style="color:#c678dd"&gt;static&lt;/span&gt; &lt;span style="color:#e06c75"&gt;instance&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;Apocalipsis&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;private&lt;/span&gt; &lt;span style="color:#c678dd"&gt;constructor&lt;/span&gt;(&lt;span style="color:#c678dd"&gt;public&lt;/span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;) {}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;static&lt;/span&gt; &lt;span style="color:#e06c75"&gt;getInstance&lt;/span&gt;()&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Apocalipsis&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;if&lt;/span&gt; (&lt;span style="color:#56b6c2"&gt;!&lt;/span&gt;&lt;span style="color:#e06c75"&gt;Apocalipsis&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;instance&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;Apocalipsis&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;instance&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#c678dd"&gt;new&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Apocalipsis&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;Soy Apocalipsis... el único&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Apocalipsis&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;instance&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;apocalipsis&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Apocalipsis&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;getInstance&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="patrones-de-diseño-habilitados"&gt;Patrones de diseño habilitados&lt;/h2&gt;
&lt;h3 id="factory-pattern"&gt;Factory Pattern&lt;/h3&gt;
&lt;p&gt;Centraliza la creación de objetos detrás de una función que decide la clase concreta:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;type&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Shoe&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;purpose&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e06c75"&gt;BalletFlat&lt;/span&gt; &lt;span style="color:#c678dd"&gt;implements&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Shoe&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;purpose&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;dancing&amp;#39;&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Boot&lt;/span&gt; &lt;span style="color:#c678dd"&gt;implements&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Shoe&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;purpose&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;woodcutting&amp;#39;&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Sneaker&lt;/span&gt; &lt;span style="color:#c678dd"&gt;implements&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Shoe&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;purpose&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;walking&amp;#39;&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Shoe&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;create&lt;/span&gt;(&lt;span style="color:#c678dd"&gt;type&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;balletFlat&amp;#39;&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;boot&amp;#39;&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;sneaker&amp;#39;&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Shoe&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;switch&lt;/span&gt; (&lt;span style="color:#c678dd"&gt;type&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;case&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;balletFlat&amp;#39;&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#c678dd"&gt;new&lt;/span&gt; &lt;span style="color:#e06c75"&gt;BalletFlat&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;case&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;boot&amp;#39;&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#c678dd"&gt;new&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Boot&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;case&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;sneaker&amp;#39;&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#c678dd"&gt;new&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Sneaker&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="builder-pattern"&gt;Builder Pattern&lt;/h3&gt;
&lt;p&gt;Construye un objeto paso a paso mediante métodos que retornan &lt;code&gt;this&lt;/code&gt;, habilitando una API fluida:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e06c75"&gt;RequestBuilder&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;private&lt;/span&gt; &lt;span style="color:#e06c75"&gt;data&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;object&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;null&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;private&lt;/span&gt; &lt;span style="color:#e06c75"&gt;method&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;get&amp;#39;&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;post&amp;#39;&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;null&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;private&lt;/span&gt; &lt;span style="color:#e06c75"&gt;url&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;null&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;setMethod&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;method&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;get&amp;#39;&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;post&amp;#39;&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#c678dd"&gt;this&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;this&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;method&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;method&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#c678dd"&gt;this&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;setData&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;data&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;object&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#c678dd"&gt;this&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;this&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;data&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;data&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#c678dd"&gt;this&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;setURL&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;url&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#c678dd"&gt;this&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;this&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;url&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;url&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#c678dd"&gt;this&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;send() {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#7f848e"&gt;// ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;new&lt;/span&gt; &lt;span style="color:#e06c75"&gt;RequestBuilder&lt;/span&gt;().&lt;span style="color:#e06c75"&gt;setURL&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;/api&amp;#39;&lt;/span&gt;).&lt;span style="color:#e06c75"&gt;setMethod&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;post&amp;#39;&lt;/span&gt;).&lt;span style="color:#e06c75"&gt;setData&lt;/span&gt;({}).&lt;span style="color:#e06c75"&gt;send&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;Las clases de TypeScript ofrecen un modelo de orientación a objetos completo: herencia, modificadores de acceso, clases abstractas para polimorfismo, accessors, miembros estáticos y un tipado estructural con la salvedad de los miembros privados. Estas piezas son el fundamento de patrones de diseño como Factory, Builder y Singleton.&lt;/p&gt;
&lt;p&gt;En el siguiente artículo abordaremos los &lt;strong&gt;genéricos&lt;/strong&gt;, la herramienta para escribir código reutilizable sin sacrificar la seguridad de tipos.&lt;/p&gt;</content:encoded></item><item><title>Estilos CSS: Animaciones con @keyframes</title><link>https://blog.dacadev.com/programacion/estilos-css/animaciones-keyframes/</link><pubDate>Thu, 18 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/programacion/estilos-css/animaciones-keyframes/</guid><dc:creator>Dacadev</dc:creator><category>programación</category><description>Domina las animaciones en CSS con @keyframes: la propiedad animation, iteraciones, direction, fill-mode, play-state, accesibilidad y rendimiento, con ejemplos en vivo.</description><media:content url="https://blog.dacadev.com/images/programming/html-and-css/css/09-animaciones-keyframes-banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#transición-vs-animación"&gt;Transición vs. animación&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#la-regla-keyframes"&gt;La regla @keyframes&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#múltiples-pasos-con-porcentajes"&gt;Múltiples pasos con porcentajes&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#la-propiedad-animation-y-sus-subpropiedades"&gt;La propiedad animation y sus subpropiedades&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#iteration-count-y-direction"&gt;iteration-count y direction&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#fill-mode-el-estado-antes-y-después"&gt;fill-mode: el estado antes y después&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#play-state-y-delay"&gt;play-state y delay&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#encadenar-varias-animaciones"&gt;Encadenar varias animaciones&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#accesibilidad-respeta-prefers-reduced-motion"&gt;Accesibilidad: respeta prefers-reduced-motion&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#rendimiento-anima-en-la-capa-de-composición"&gt;Rendimiento: anima en la capa de composición&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#conclusión"&gt;Conclusión&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;p&gt;Una transición anima el salto entre dos estados; pero cuando necesitas movimiento continuo, varios pasos intermedios o una secuencia que se repite —un spinner de carga, un latido, un texto que aparece— necesitas algo más expresivo. Ahí entran las &lt;strong&gt;animaciones con &lt;code&gt;@keyframes&lt;/code&gt;&lt;/strong&gt;, el sistema de CSS para describir secuencias de movimiento complejas de forma declarativa, sin una sola línea de JavaScript.&lt;/p&gt;
&lt;p&gt;Esta entrega extiende la serie &lt;strong&gt;Estilos CSS&lt;/strong&gt;, retomando justo donde lo dejaron las transiciones y transformaciones. Cubriremos la regla &lt;code&gt;@keyframes&lt;/code&gt;, todas las subpropiedades de &lt;code&gt;animation&lt;/code&gt;, y las consideraciones de accesibilidad y rendimiento que separan una animación profesional de una que marea al usuario.&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Aprenderás a definir secuencias con &lt;code&gt;@keyframes&lt;/code&gt;, a controlarlas con la propiedad &lt;code&gt;animation&lt;/code&gt; y sus ocho subpropiedades, y a respetar las preferencias de movimiento del usuario con &lt;code&gt;prefers-reduced-motion&lt;/code&gt;.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="transición-vs-animación"&gt;Transición vs. animación&lt;/h2&gt;
&lt;p&gt;Aunque ambas producen movimiento, resuelven problemas distintos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Una &lt;strong&gt;transición&lt;/strong&gt; (&lt;code&gt;transition&lt;/code&gt;) interpola entre el estado actual y uno nuevo. Necesita un disparador —un &lt;code&gt;:hover&lt;/code&gt;, un cambio de clase— y va de un punto A a un punto B.&lt;/li&gt;
&lt;li&gt;Una &lt;strong&gt;animación&lt;/strong&gt; (&lt;code&gt;animation&lt;/code&gt;) ejecuta una secuencia definida en &lt;code&gt;@keyframes&lt;/code&gt;. No necesita disparador: puede arrancar sola, repetirse indefinidamente y pasar por múltiples estados intermedios.&lt;/li&gt;
&lt;/ul&gt;




 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Regla práctica: usa &lt;code&gt;transition&lt;/code&gt; para cambios de estado provocados por interacción; usa &lt;code&gt;animation&lt;/code&gt; para movimiento autónomo, cíclico o multipaso.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="la-regla-keyframes"&gt;La regla @keyframes&lt;/h2&gt;
&lt;p&gt;Una animación se define en dos partes: la &lt;strong&gt;secuencia&lt;/strong&gt; (con &lt;code&gt;@keyframes&lt;/code&gt;) y su &lt;strong&gt;aplicación&lt;/strong&gt; (con la propiedad &lt;code&gt;animation&lt;/code&gt;). La regla &lt;code&gt;@keyframes&lt;/code&gt; recibe un nombre y describe los estados de la animación en distintos momentos, expresados como porcentajes del 0% al 100% (o con las palabras clave &lt;code&gt;from&lt;/code&gt; y &lt;code&gt;to&lt;/code&gt;).&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;@&lt;span style="color:#c678dd"&gt;keyframes&lt;/span&gt; &lt;span style="color:#e06c75"&gt;aparecer&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;from&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;opacity&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;; &lt;span style="color:#c678dd"&gt;transform&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;translateY&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;rem&lt;/span&gt;); }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;to&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;opacity&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;; &lt;span style="color:#c678dd"&gt;transform&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;translateY&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;); }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;elemento&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;animation&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;aparecer&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0.6&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;s&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;ease-out&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border:1px solid #d0d0d0;border-radius:.5rem;padding:1.5rem;background:#fff;color:#111;margin:1rem 0;font-family:Helvetica,Arial,sans-serif;"&gt;
 &lt;style&gt;
 @keyframes csanim-aparecer {
 from { opacity:0; transform:translateY(1rem); }
 to { opacity:1; transform:translateY(0); }
 }
 .csanim-fade { display:inline-block; background:#2a9da9; color:#fff; padding:.8em 1.4em; border-radius:.4em; animation:csanim-aparecer 1.2s ease-out infinite; }
 &lt;/style&gt;
 &lt;span class="csanim-fade"&gt;Aparezco con fade + desplazamiento&lt;/span&gt;
 &lt;p style="margin:.75rem 0 0;color:#555;"&gt;La secuencia se repite para que puedas observarla.&lt;/p&gt;
&lt;/div&gt;
&lt;h3 id="múltiples-pasos-con-porcentajes"&gt;Múltiples pasos con porcentajes&lt;/h3&gt;
&lt;p&gt;El verdadero poder de &lt;code&gt;@keyframes&lt;/code&gt; aparece con pasos intermedios. Cada porcentaje es una &amp;ldquo;foto&amp;rdquo; del estado en ese momento de la animación:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;@&lt;span style="color:#c678dd"&gt;keyframes&lt;/span&gt; &lt;span style="color:#e06c75"&gt;latido&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;0&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;%&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;transform&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;scale&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;); }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;15&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;%&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;transform&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;scale&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;1.25&lt;/span&gt;); }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;30&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;%&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;transform&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;scale&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;); }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;45&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;%&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;transform&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;scale&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;1.15&lt;/span&gt;); }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;60&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;%&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;transform&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;scale&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;); }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border:1px solid #d0d0d0;border-radius:.5rem;padding:1.5rem;background:#fff;color:#111;margin:1rem 0;font-family:Helvetica,Arial,sans-serif;text-align:center;"&gt;
 &lt;style&gt;
 @keyframes csanim-latido {
 0% { transform:scale(1); }
 15% { transform:scale(1.25); }
 30% { transform:scale(1); }
 45% { transform:scale(1.15); }
 60% { transform:scale(1); }
 100% { transform:scale(1); }
 }
 .csanim-heart { display:inline-block; font-size:2.5rem; color:#c0392b; animation:csanim-latido 1.5s ease-in-out infinite; }
 &lt;/style&gt;
 &lt;span class="csanim-heart"&gt;♥&lt;/span&gt;
&lt;/div&gt;
&lt;h2 id="la-propiedad-animation-y-sus-subpropiedades"&gt;La propiedad animation y sus subpropiedades&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;animation&lt;/code&gt; es una propiedad abreviada que agrupa ocho subpropiedades. Conviene conocerlas por separado para tener control fino:&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Subpropiedad&lt;/th&gt;
 &lt;th&gt;Función&lt;/th&gt;
 &lt;th&gt;Ejemplo&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;animation-name&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Nombre del &lt;code&gt;@keyframes&lt;/code&gt; a ejecutar&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;aparecer&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;animation-duration&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Duración de un ciclo&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;0.6s&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;animation-timing-function&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Curva de progreso&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;ease-in-out&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;animation-delay&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Espera antes de iniciar&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;200ms&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;animation-iteration-count&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Número de repeticiones&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;infinite&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;animation-direction&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Sentido de reproducción&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;alternate&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;animation-fill-mode&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Estilos antes/después de animar&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;forwards&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;animation-play-state&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Reproducir o pausar&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;paused&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;La forma abreviada las combina en una sola declaración:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;spinner&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;animation&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;girar&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;s&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;linear&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;infinite&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#7f848e"&gt;/* name | duration | timing-function | iteration-count */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="iteration-count-y-direction"&gt;iteration-count y direction&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;animation-iteration-count&lt;/code&gt; define cuántas veces se ejecuta (&lt;code&gt;infinite&lt;/code&gt; para un bucle perpetuo). &lt;code&gt;animation-direction&lt;/code&gt; controla el sentido:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;normal&lt;/code&gt; — siempre de 0% a 100%.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;reverse&lt;/code&gt; — siempre de 100% a 0%.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;alternate&lt;/code&gt; — alterna ida y vuelta en cada ciclo.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;alternate-reverse&lt;/code&gt; — igual, pero empezando al revés.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;El caso clásico es un &lt;strong&gt;spinner&lt;/strong&gt; de carga, que combina rotación infinita con velocidad constante:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;@&lt;span style="color:#c678dd"&gt;keyframes&lt;/span&gt; &lt;span style="color:#e06c75"&gt;girar&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;to&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;transform&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;rotate&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;360&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;deg&lt;/span&gt;); } }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;spinner&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;animation&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;girar&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0.8&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;s&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;linear&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;infinite&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border:1px solid #d0d0d0;border-radius:.5rem;padding:1.5rem;background:#fff;color:#111;margin:1rem 0;font-family:Helvetica,Arial,sans-serif;text-align:center;"&gt;
 &lt;style&gt;
 @keyframes csanim-girar { to { transform:rotate(360deg); } }
 .csanim-spinner { display:inline-block; width:2.5rem; height:2.5rem; border:.3rem solid #d6eaf0; border-top-color:#2a9da9; border-radius:50%; animation:csanim-girar .8s linear infinite; }
 &lt;/style&gt;
 &lt;span class="csanim-spinner" role="status" aria-label="Cargando"&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;h3 id="fill-mode-el-estado-antes-y-después"&gt;fill-mode: el estado antes y después&lt;/h3&gt;
&lt;p&gt;Por defecto, un elemento vuelve a su estilo original en cuanto la animación termina. &lt;code&gt;animation-fill-mode&lt;/code&gt; cambia ese comportamiento:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;none&lt;/code&gt; (por defecto) — no conserva estilos fuera de la ejecución.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;forwards&lt;/code&gt; — mantiene el estado del último keyframe al terminar.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;backwards&lt;/code&gt; — aplica el primer keyframe durante el &lt;code&gt;delay&lt;/code&gt;, antes de arrancar.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;both&lt;/code&gt; — combina &lt;code&gt;forwards&lt;/code&gt; y &lt;code&gt;backwards&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;forwards&lt;/code&gt; es esencial cuando quieres que el elemento permanezca en su estado final (por ejemplo, un mensaje que aparece y se queda visible):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;toast&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;animation&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;aparecer&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0.5&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;s&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;ease-out&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;forwards&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="play-state-y-delay"&gt;play-state y delay&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;animation-play-state&lt;/code&gt; permite pausar (&lt;code&gt;paused&lt;/code&gt;) y reanudar (&lt;code&gt;running&lt;/code&gt;) una animación, típicamente al combinarla con &lt;code&gt;:hover&lt;/code&gt;. Aquí, la barra de progreso se anima sola pero se congela al pasar el cursor:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;@&lt;span style="color:#c678dd"&gt;keyframes&lt;/span&gt; &lt;span style="color:#e06c75"&gt;cargar&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;from&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;width&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;; } &lt;span style="color:#e06c75"&gt;to&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;width&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;100&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;%&lt;/span&gt;; } }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;barra__relleno&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;animation&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;cargar&lt;/span&gt; &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;s&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;ease-in-out&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;infinite&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;barra&lt;/span&gt;:&lt;span style="color:#61afef"&gt;hover&lt;/span&gt; .&lt;span style="color:#e5c07b"&gt;barra__relleno&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;animation-play-state&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;paused&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border:1px solid #d0d0d0;border-radius:.5rem;padding:1.5rem;background:#fff;color:#111;margin:1rem 0;font-family:Helvetica,Arial,sans-serif;"&gt;
 &lt;style&gt;
 @keyframes csanim-cargar { 0% { width:0; } 100% { width:100%; } }
 .csanim-barra { background:#e5e8e8; border-radius:1rem; overflow:hidden; height:1rem; }
 .csanim-barra__relleno { height:100%; width:0; background:linear-gradient(to right,#2a9da9,#16828d); border-radius:1rem; animation:csanim-cargar 3s ease-in-out infinite; }
 .csanim-barra:hover .csanim-barra__relleno { animation-play-state:paused; }
 &lt;/style&gt;
 &lt;div class="csanim-barra"&gt;&lt;div class="csanim-barra__relleno"&gt;&lt;/div&gt;&lt;/div&gt;
 &lt;p style="margin:.75rem 0 0;color:#555;"&gt;Pasa el cursor sobre la barra para pausar la animación.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="encadenar-varias-animaciones"&gt;Encadenar varias animaciones&lt;/h2&gt;
&lt;p&gt;Puedes aplicar varias animaciones a un mismo elemento separándolas con comas. Cada una mantiene su propia duración, retraso y curva, lo que permite componer comportamientos independientes:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;elemento&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;animation&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;aparecer&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0.5&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;s&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;ease-out&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;flotar&lt;/span&gt; &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;s&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;ease-in-out&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0.5&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;s&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;infinite&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;alternate&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border:1px solid #d0d0d0;border-radius:.5rem;padding:1.5rem;background:#fff;color:#111;margin:1rem 0;font-family:Helvetica,Arial,sans-serif;text-align:center;"&gt;
 &lt;style&gt;
 @keyframes csanim-flotar { from { transform:translateY(0); } to { transform:translateY(-12px); } }
 .csanim-flota { display:inline-block; background:#f39c12; color:#fff; padding:1em 1.6em; border-radius:.5em; box-shadow:0 .4em .8em rgba(0,0,0,.2); animation:csanim-flotar 1.8s ease-in-out infinite alternate; }
 &lt;/style&gt;
 &lt;span class="csanim-flota"&gt;Floto suavemente&lt;/span&gt;
&lt;/div&gt;
&lt;h2 id="accesibilidad-respeta-prefers-reduced-motion"&gt;Accesibilidad: respeta prefers-reduced-motion&lt;/h2&gt;
&lt;p&gt;El movimiento excesivo puede causar mareos o malestar a personas con sensibilidad vestibular. Los sistemas operativos exponen una preferencia de &amp;ldquo;reducir movimiento&amp;rdquo;, y CSS la consulta con la media query &lt;code&gt;prefers-reduced-motion&lt;/code&gt;. Es una responsabilidad profesional desactivar o atenuar las animaciones no esenciales cuando el usuario lo solicita:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;@&lt;span style="color:#c678dd"&gt;media&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;(&lt;/span&gt;&lt;span style="color:#e06c75"&gt;prefers-reduced-motion&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e06c75"&gt;reduce&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;)&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;*,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;*&lt;/span&gt;::&lt;span style="color:#61afef"&gt;before&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;*&lt;/span&gt;::&lt;span style="color:#61afef"&gt;after&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;animation-duration&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;0.01&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;ms&lt;/span&gt; &lt;span style="color:#7f848e"&gt;!important&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;animation-iteration-count&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#7f848e"&gt;!important&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;transition-duration&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;0.01&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;ms&lt;/span&gt; &lt;span style="color:#7f848e"&gt;!important&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Ignorar &lt;code&gt;prefers-reduced-motion&lt;/code&gt; es un fallo de accesibilidad real. Reserva las animaciones llamativas para lo decorativo y asegúrate de que la interfaz siga siendo plenamente funcional cuando el movimiento se reduce.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="rendimiento-anima-en-la-capa-de-composición"&gt;Rendimiento: anima en la capa de composición&lt;/h2&gt;
&lt;p&gt;La misma regla de oro de las transiciones aplica aquí: anima propiedades que solo afecten la etapa de &lt;strong&gt;composición&lt;/strong&gt; del navegador —&lt;code&gt;transform&lt;/code&gt; y &lt;code&gt;opacity&lt;/code&gt;— en lugar de propiedades que disparen &lt;em&gt;layout&lt;/em&gt; o &lt;em&gt;paint&lt;/em&gt; (&lt;code&gt;width&lt;/code&gt;, &lt;code&gt;height&lt;/code&gt;, &lt;code&gt;top&lt;/code&gt;, &lt;code&gt;left&lt;/code&gt;, &lt;code&gt;margin&lt;/code&gt;).&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;/* ❌ Costoso: recalcula layout en cada frame */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;@&lt;span style="color:#c678dd"&gt;keyframes&lt;/span&gt; &lt;span style="color:#e06c75"&gt;mover-malo&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;to&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;left&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;200&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;px&lt;/span&gt;; } }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;/* ✅ Eficiente: solo composición, fluido a 60 fps */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;@&lt;span style="color:#c678dd"&gt;keyframes&lt;/span&gt; &lt;span style="color:#e06c75"&gt;mover-bien&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;to&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;transform&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;translateX&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;200&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;px&lt;/span&gt;); } }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



 
 





 


&lt;div class="notice tip"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z" /&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Tip&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Si una animación se ve entrecortada, lo primero que debes revisar es qué propiedades estás animando. Reescribir un &lt;code&gt;left&lt;/code&gt;/&lt;code&gt;top&lt;/code&gt; como &lt;code&gt;transform: translate()&lt;/code&gt; suele eliminar el &lt;em&gt;jank&lt;/em&gt; de inmediato.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;Las animaciones con &lt;code&gt;@keyframes&lt;/code&gt; te dan un lenguaje declarativo para describir movimiento complejo: secuencias multipaso, bucles infinitos y comportamientos compuestos, todo en CSS puro. Dominar la propiedad &lt;code&gt;animation&lt;/code&gt; y sus subpropiedades —especialmente &lt;code&gt;fill-mode&lt;/code&gt;, &lt;code&gt;iteration-count&lt;/code&gt; y &lt;code&gt;play-state&lt;/code&gt;— te permite construir spinners, indicadores de carga y microinteracciones pulidas. Y recuerda: anima &lt;code&gt;transform&lt;/code&gt; y &lt;code&gt;opacity&lt;/code&gt;, y respeta siempre &lt;code&gt;prefers-reduced-motion&lt;/code&gt;.&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;🚀 Con esta entrega completas el recorrido de la serie &lt;strong&gt;Estilos CSS&lt;/strong&gt;: desde la cascada y los selectores hasta el layout, el posicionamiento, los fondos, las transformaciones y, ahora, las animaciones. Tienes el repertorio completo para escribir CSS expresivo, accesible y de alto rendimiento.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
</content:encoded></item><item><title>TypeScript: Interfaces y contratos de tipos</title><link>https://blog.dacadev.com/typescript/interfaces/</link><pubDate>Thu, 18 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/typescript/interfaces/</guid><dc:creator>Dacadev</dc:creator><category>programación</category><description>Domina las interfaces en TypeScript: contratos extensibles, herencia con extends, implementación en clases, diferencias con type y declaration merging.</description><media:content url="https://blog.dacadev.com/images/typescript/interfaces/banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#bases-definir-y-extender-interfaces"&gt;Bases: definir y extender interfaces&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#estructuras-complejas-interfaces-anidadas"&gt;Estructuras complejas: interfaces anidadas&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#métodos-en-la-interfaz"&gt;Métodos en la interfaz&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#implementar-interfaces-en-clases"&gt;Implementar interfaces en clases&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#interfaces-para-tipar-funciones"&gt;Interfaces para tipar funciones&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#interfaces-frente-a-alias-de-tipo"&gt;Interfaces frente a alias de tipo&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#1-composición"&gt;1. Composición&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#2-restricción-al-extender"&gt;2. Restricción al extender&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#3-declaration-merging"&gt;3. Declaration merging&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#implementación-con-readonly-y-múltiples-contratos"&gt;Implementación con readonly y múltiples contratos&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#conclusión"&gt;Conclusión&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;





 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Quinto artículo de la serie sobre &lt;strong&gt;TypeScript&lt;/strong&gt;. Estudiaremos las interfaces como contratos extensibles, su herencia con &lt;code&gt;extends&lt;/code&gt;, su implementación en clases con &lt;code&gt;implements&lt;/code&gt;, y sus diferencias frente a los alias de tipo.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Una &lt;strong&gt;interface&lt;/strong&gt; en TypeScript define la forma que deben cumplir los objetos. A primera vista se parece a un alias de tipo, pero su rasgo distintivo es la &lt;strong&gt;extensibilidad&lt;/strong&gt;: las interfaces están diseñadas para componerse, heredarse y servir como base de contratos más complejos. Analicemos cuándo y cómo usarlas.&lt;/p&gt;
&lt;h2 id="bases-definir-y-extender-interfaces"&gt;Bases: definir y extender interfaces&lt;/h2&gt;
&lt;p&gt;Una interface declara la estructura de un objeto. Con &lt;code&gt;extends&lt;/code&gt;, una interface puede heredar de otra y ampliar su contrato:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;interface&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Hero&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;age?&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;powers&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;[];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;getName&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;?:&lt;/span&gt; () &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;interface&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Avenger&lt;/span&gt; &lt;span style="color:#c678dd"&gt;extends&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Hero&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;marvel&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;flash&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;Hero&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Barry Allen&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;age&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;24&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;powers&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; [&lt;span style="color:#98c379"&gt;&amp;#39;super velocidad&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;viajar en el tiempo&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;Avenger&lt;/code&gt; hereda todos los miembros de &lt;code&gt;Hero&lt;/code&gt; y añade &lt;code&gt;marvel&lt;/code&gt;. Esta composición es la base del diseño orientado a contratos.&lt;/p&gt;
&lt;h2 id="estructuras-complejas-interfaces-anidadas"&gt;Estructuras complejas: interfaces anidadas&lt;/h2&gt;
&lt;p&gt;Las interfaces pueden referenciarse entre sí para modelar estructuras de datos compuestas:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;interface&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Client&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;age?&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;address?&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;Address&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;interface&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Address&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;id&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;zip&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;city&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;client&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;Client&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;David&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;address&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;id&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;125&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;zip&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;KYD 234&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;city&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Chía&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;client2&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;Client&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Melissa&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;age&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;30&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;Client&lt;/code&gt; referencia a &lt;code&gt;Address&lt;/code&gt; como un campo opcional, lo que permite componer entidades de dominio sin acoplarlas en una sola definición monolítica.&lt;/p&gt;
&lt;h2 id="métodos-en-la-interfaz"&gt;Métodos en la interfaz&lt;/h2&gt;
&lt;p&gt;Al igual que los alias de tipo, las interfaces pueden declarar métodos como parte del contrato:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;interface&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Client&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;age?&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;address?&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;Address&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;getFullAddress&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;id&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#c678dd"&gt;void&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Declarar métodos en una interface es válido, pero implica que el objeto que la cumpla debe implementarlos. En la práctica, cuando un contrato requiere comportamiento, lo más limpio es implementarlo mediante una clase.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="implementar-interfaces-en-clases"&gt;Implementar interfaces en clases&lt;/h2&gt;
&lt;p&gt;Una clase adopta uno o varios contratos con la palabra clave &lt;code&gt;implements&lt;/code&gt;. Esto garantiza, en compilación, que la clase provee todo lo que el contrato exige:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;interface&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Xmen&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;realName&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;mutantPower&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;id&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;interface&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Human&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;age&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Mutant&lt;/span&gt; &lt;span style="color:#c678dd"&gt;implements&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Xmen&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;Human&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;public&lt;/span&gt; &lt;span style="color:#e06c75"&gt;age&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;public&lt;/span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;public&lt;/span&gt; &lt;span style="color:#e06c75"&gt;realName&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;mutantPower&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;id&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Hola mundo&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;Mutant&lt;/code&gt; implementa simultáneamente &lt;code&gt;Xmen&lt;/code&gt; y &lt;code&gt;Human&lt;/code&gt;. Si omitiera cualquier miembro requerido, el compilador lo rechazaría.&lt;/p&gt;
&lt;h2 id="interfaces-para-tipar-funciones"&gt;Interfaces para tipar funciones&lt;/h2&gt;
&lt;p&gt;Aunque es poco frecuente, una interface puede describir la firma de una función antes de asignarle una implementación:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;interface&lt;/span&gt; &lt;span style="color:#e06c75"&gt;AddTwoNumbers&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (&lt;span style="color:#e06c75"&gt;a&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;b&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;addNumbers&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;AddTwoNumbers&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;addNumbers&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;a&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;b&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;+&lt;/span&gt; &lt;span style="color:#e06c75"&gt;b&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="interfaces-frente-a-alias-de-tipo"&gt;Interfaces frente a alias de tipo&lt;/h2&gt;
&lt;p&gt;Esta es la decisión de diseño más común. Las tres diferencias clave:&lt;/p&gt;
&lt;h3 id="1-composición"&gt;1. Composición&lt;/h3&gt;
&lt;p&gt;Los alias de tipo componen mediante operaciones de conjuntos (&lt;code&gt;|&lt;/code&gt;, &lt;code&gt;&amp;amp;&lt;/code&gt;); las interfaces componen mediante &lt;code&gt;extends&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;type&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Food&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;calories&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;; &lt;span style="color:#e06c75"&gt;tasty&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;boolean&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;type&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Sushi&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Food&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;&amp;amp;&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;salty&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;boolean&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;interface&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FoodI&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;calories&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;; &lt;span style="color:#e06c75"&gt;tasty&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;boolean&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;interface&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SushiI&lt;/span&gt; &lt;span style="color:#c678dd"&gt;extends&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FoodI&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;salty&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;boolean&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="2-restricción-al-extender"&gt;2. Restricción al extender&lt;/h3&gt;
&lt;p&gt;Al extender una interface, no puedes &lt;strong&gt;cambiar&lt;/strong&gt; el tipo de un miembro heredado, solo añadir o restringir de forma compatible. Una incompatibilidad genera error:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;interface&lt;/span&gt; &lt;span style="color:#e06c75"&gt;A&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;good&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;x&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;bad&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;x&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;interface&lt;/span&gt; &lt;span style="color:#e06c75"&gt;B&lt;/span&gt; &lt;span style="color:#c678dd"&gt;extends&lt;/span&gt; &lt;span style="color:#e06c75"&gt;A&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;good&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;x&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;bad&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;x&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// Error TS2430: &amp;#39;B&amp;#39; extiende incorrectamente &amp;#39;A&amp;#39;.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="3-declaration-merging"&gt;3. Declaration merging&lt;/h3&gt;
&lt;p&gt;Varias interfaces con el mismo nombre en el mismo ámbito &lt;strong&gt;se fusionan automáticamente&lt;/strong&gt;; varios alias de tipo con el mismo nombre producen un error de compilación:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;interface&lt;/span&gt; &lt;span style="color:#e06c75"&gt;User&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;interface&lt;/span&gt; &lt;span style="color:#e06c75"&gt;User&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;age&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt; } &lt;span style="color:#7f848e"&gt;// se fusiona
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;User&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Ashley&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;age&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;30&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;type&lt;/span&gt; &lt;span style="color:#e06c75"&gt;User&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt; } &lt;span style="color:#7f848e"&gt;// Error TS2300: identificador duplicado
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;type&lt;/span&gt; &lt;span style="color:#e06c75"&gt;User&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;age&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt; } &lt;span style="color:#7f848e"&gt;// Error TS2300
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El &lt;em&gt;declaration merging&lt;/em&gt; respeta los tipos existentes: no puedes redefinir un miembro ya declarado con otro tipo.&lt;/p&gt;
&lt;pre class="mermaid"&gt;flowchart TD
 Q{¿Necesitas extensibilidad,&amp;lt;br/&amp;gt;implements o merging?}
 Q -- Sí --&amp;gt; I[Usa interface]
 Q -- &amp;#34;No (uniones, tuplas, mapeos)&amp;#34; --&amp;gt; T[Usa type]
&lt;/pre&gt;

&lt;h2 id="implementación-con-readonly-y-múltiples-contratos"&gt;Implementación con readonly y múltiples contratos&lt;/h2&gt;
&lt;p&gt;Las interfaces admiten propiedades &lt;code&gt;readonly&lt;/code&gt; y permiten que una clase cumpla varios contratos a la vez:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;interface&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Animal&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;readonly&lt;/span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;eat&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;food&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#c678dd"&gt;void&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;sleep&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;hours&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#c678dd"&gt;void&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;interface&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Feline&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;meow&lt;/span&gt;()&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#c678dd"&gt;void&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Cat&lt;/span&gt; &lt;span style="color:#c678dd"&gt;implements&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Animal&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;Feline&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Whiskers&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;eat&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;food&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;) { &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;info&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;Ate some&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;food&lt;/span&gt;) }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;sleep&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;hours&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;) { &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;info&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;Slept for&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;hours&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;hours&amp;#39;&lt;/span&gt;) }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;meow() {&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;info&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;Meow&amp;#39;&lt;/span&gt;) }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;Las interfaces son el mecanismo de TypeScript para definir contratos extensibles y verificables. Elige una interface cuando necesites herencia con &lt;code&gt;extends&lt;/code&gt;, implementación en clases con &lt;code&gt;implements&lt;/code&gt; o &lt;em&gt;declaration merging&lt;/em&gt;; reserva los alias de tipo para uniones, intersecciones, tuplas y tipos mapeados.&lt;/p&gt;
&lt;p&gt;En el próximo artículo profundizaremos en las &lt;strong&gt;clases&lt;/strong&gt;, la herencia, los modificadores de acceso y los patrones de diseño que habilitan.&lt;/p&gt;</content:encoded></item><item><title>SQL: Consultas a Múltiples Tablas con JOINs</title><link>https://blog.dacadev.com/programacion/sql/05-consultas-multiples-tablas-joins/</link><pubDate>Wed, 17 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/programacion/sql/05-consultas-multiples-tablas-joins/</guid><dc:creator>Dacadev</dc:creator><category>programación</category><description>Aprende a usar JOIN en SQL para consultar múltiples tablas, aplicar self join y combinar resultados con UNION, INTERSECT y EXCEPT.</description><media:content url="https://blog.dacadev.com/images/programming/sql/querying-multiple-tables/banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#producto-cartesiano"&gt;Producto cartesiano&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#inner-join"&gt;Inner Join&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#unir-3-o-más-tablas"&gt;Unir 3 o más tablas&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#subqueries-como-tablas"&gt;Subqueries como tablas&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#misma-tabla-dos-veces"&gt;Misma tabla dos veces&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#self-join"&gt;Self join&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#teoría-de-conjuntos"&gt;Teoría de conjuntos&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#union"&gt;UNION&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#intersect"&gt;INTERSECT&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#except"&gt;EXCEPT&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#reglas-de-operaciones-de-conjuntos"&gt;Reglas de operaciones de conjuntos&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#ordenar-resultados-con-alias-válidos"&gt;Ordenar resultados con alias válidos&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#el-orden-de-las-operaciones-importa"&gt;El orden de las operaciones importa&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#cierre"&gt;Cierre&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;p&gt;Cuando una aplicación modela procesos reales, una sola tabla rara vez contiene todo el contexto. Clientes requieren direcciones, películas requieren actores y reportes operativos combinan varias entidades. Por eso, dominar &lt;strong&gt;consultas a múltiples tablas&lt;/strong&gt; y entender cada &lt;code&gt;JOIN en SQL&lt;/code&gt; es clave para escribir consultas correctas, expresivas y mantenibles.&lt;/p&gt;
&lt;p&gt;En el artículo anterior trabajamos &lt;a href="https://blog.dacadev.com/programacion/sql/04-agrupamiento-funciones-agregadas"



 


&gt;agrupamiento y funciones agregadas&lt;/a&gt;. Ahora conectaremos ese análisis con relaciones entre tablas.&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Aprenderás a usar &lt;code&gt;INNER JOIN&lt;/code&gt;, unir tres o más tablas, reutilizar tablas con alias, aplicar &lt;code&gt;SELF JOIN&lt;/code&gt; y combinar resultados con &lt;code&gt;UNION&lt;/code&gt;, &lt;code&gt;INTERSECT&lt;/code&gt; y &lt;code&gt;EXCEPT&lt;/code&gt;.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="producto-cartesiano"&gt;Producto cartesiano&lt;/h2&gt;
&lt;p&gt;El &lt;strong&gt;producto cartesiano&lt;/strong&gt; aparece cuando haces un &lt;code&gt;JOIN&lt;/code&gt; entre dos tablas sin definir la condición que relaciona sus filas. SQL combina cada fila de la primera tabla con cada fila de la segunda.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;, &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;address&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;address&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------------+-----------+----------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;address&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------------+-----------+----------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;MARY&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SMITH&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;47&lt;/span&gt; &lt;span style="color:#e06c75"&gt;MySakila&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Drive&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;PATRICIA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JOHNSON&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;47&lt;/span&gt; &lt;span style="color:#e06c75"&gt;MySakila&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Drive&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;LINDA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;WILLIAMS&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;47&lt;/span&gt; &lt;span style="color:#e06c75"&gt;MySakila&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Drive&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FREDDIE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DUGGAN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1325&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Fukuyama&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Street&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;WADE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DELVALLE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1325&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Fukuyama&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Street&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;AUSTIN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CINTRON&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1325&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Fukuyama&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Street&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------------+-----------+----------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;361197&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;03&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El resultado tiene &lt;code&gt;361,197&lt;/code&gt; filas porque &lt;code&gt;customer&lt;/code&gt; tiene &lt;code&gt;599&lt;/code&gt; registros y &lt;code&gt;address&lt;/code&gt; tiene &lt;code&gt;603&lt;/code&gt;: &lt;code&gt;599 * 603 = 361197&lt;/code&gt;. Normalmente esto indica que falta una condición &lt;code&gt;ON&lt;/code&gt;.&lt;/p&gt;




 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Un &lt;code&gt;JOIN&lt;/code&gt; sin condición explícita puede multiplicar el volumen de datos y degradar el rendimiento. Revisa siempre que exista una relación clara entre las tablas.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="inner-join"&gt;Inner Join&lt;/h2&gt;
&lt;p&gt;El &lt;strong&gt;&lt;code&gt;INNER JOIN&lt;/code&gt;&lt;/strong&gt; retorna solo las filas que tienen coincidencia en ambas tablas según la condición definida en &lt;code&gt;ON&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;, &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;address&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;address&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;address_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;address_id&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+--------------+----------------------------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;address&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+--------------+----------------------------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;MARY&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SMITH&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1913&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Hanoi&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Way&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;PATRICIA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JOHNSON&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1121&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Loja&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Avenue&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;LINDA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;WILLIAMS&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;692&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Joliet&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Street&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FREDDIE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DUGGAN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1103&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Quilmes&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Boulevard&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;WADE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DELVALLE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1331&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Usak&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Boulevard&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;AUSTIN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CINTRON&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1325&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Fukuyama&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Street&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+--------------+----------------------------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;599&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;00&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Aunque muchos motores interpretan &lt;code&gt;JOIN&lt;/code&gt; como &lt;code&gt;INNER JOIN&lt;/code&gt;, escribirlo explícitamente mejora la legibilidad cuando aparecen otros tipos de unión.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;, &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;address&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt; &lt;span style="color:#c678dd"&gt;INNER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;address&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;address_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;address_id&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="unir-3-o-más-tablas"&gt;Unir 3 o más tablas&lt;/h2&gt;
&lt;p&gt;Para unir más de dos tablas, repetimos el patrón: otro &lt;code&gt;INNER JOIN&lt;/code&gt; y otra condición &lt;code&gt;ON&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;, &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;ct&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;city&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;INNER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;address&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;address_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;address_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;INNER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;city&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ct&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;city_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ct&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;city_id&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+--------------+----------------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;city&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+--------------+----------------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JULIE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SANCHEZ&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;A&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Corua&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;La&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Corua&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;PEGGY&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;MYERS&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Abha&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;TOM&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;MILNER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Abu&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Dhabi&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;BYRON&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;BOX&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Zhezqazghan&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;GUY&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;BROWNLEE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Zhoushan&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;RONNIE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;RICKETTS&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Ziguinchor&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+--------------+----------------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;599&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;03&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;SQL es declarativo: describes qué resultado necesitas y el optimizador decide cómo ejecutarlo. El orden textual de las tablas no necesariamente define el orden físico del plan.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="subqueries-como-tablas"&gt;Subqueries como tablas&lt;/h2&gt;
&lt;p&gt;Una &lt;strong&gt;subquery&lt;/strong&gt; puede actuar como tabla derivada dentro de un &lt;code&gt;JOIN&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;, &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;addr&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;address&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;addr&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;city&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;INNER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; (&lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;address_id&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;address&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;ct&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;city&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;address&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;INNER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;city&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ct&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;city_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ct&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;city_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;district&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;California&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; ) &lt;span style="color:#e06c75"&gt;addr&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;address_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;addr&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;address_id&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------------+-----------+------------------------+----------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;address&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;city&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------------+-----------+------------------------+----------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;PATRICIA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JOHNSON&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1121&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Loja&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Avenue&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;San&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Bernardino&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;BETTY&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;WHITE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;770&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Bydgoszcz&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Avenue&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Citrus&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Heights&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ALICE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;STEWART&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1135&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Izumisano&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Parkway&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Fontana&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JACOB&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;LANCE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1866&lt;/span&gt; &lt;span style="color:#e06c75"&gt;al&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#e06c75"&gt;Qatif&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Avenue&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;El&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Monte&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;RENE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;MCALISTER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1895&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Zhezqazghan&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Drive&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Garden&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Grove&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------------+-----------+------------------------+----------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;9&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;00&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Aquí &lt;code&gt;addr&lt;/code&gt; contiene direcciones de California junto con su ciudad, y luego se une con &lt;code&gt;customer&lt;/code&gt; mediante &lt;code&gt;address_id&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="misma-tabla-dos-veces"&gt;Misma tabla dos veces&lt;/h2&gt;
&lt;p&gt;Algunas consultas necesitan aplicar condiciones distintas sobre la misma entidad. Para eso usamos alias diferentes, incluso si la tabla física es la misma.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;title&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;INNER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film_actor&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fa1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fa1&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;INNER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;actor&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fa1&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;actor_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a1&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;actor_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;INNER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film_actor&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fa2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fa2&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;INNER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;actor&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fa2&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;actor_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a2&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;actor_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;a1&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;CATE&amp;#39;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;AND&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a1&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;MCQUEEN&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;AND&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;a2&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;CUBA&amp;#39;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;AND&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a2&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;BIRCH&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;title&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;BLOOD&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ARGONAUTS&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;TOWERS&lt;/span&gt; &lt;span style="color:#e06c75"&gt;HURRICANE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;2&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;00&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Esta consulta busca películas donde participaron ambos actores. Si declaramos la tabla una sola vez y usamos &lt;code&gt;OR&lt;/code&gt;, el significado cambia: buscamos películas donde participó cualquiera de los dos.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;title&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;INNER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film_actor&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fa&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fa&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;INNER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;actor&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fa&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;actor_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;actor_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; ((&lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;CATE&amp;#39;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;AND&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;MCQUEEN&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;OR&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;CUBA&amp;#39;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;AND&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;BIRCH&amp;#39;&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;----------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;title&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;----------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ATLANTIS&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CAUSE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;BLOOD&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ARGONAUTS&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;COMMANDMENTS&lt;/span&gt; &lt;span style="color:#e06c75"&gt;EXPRESS&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;VOLCANO&lt;/span&gt; &lt;span style="color:#e06c75"&gt;TEXAS&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;WATERSHIP&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FRONTIER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;----------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;54&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;00&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="self-join"&gt;Self join&lt;/h2&gt;
&lt;p&gt;Un &lt;strong&gt;self join&lt;/strong&gt; ocurre cuando una tabla se une consigo misma. Es común en relaciones autorreferenciales: empleados y managers, categorías padre e hijas, o películas y precuelas.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;title&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;f_prnt&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;title&lt;/span&gt; &lt;span style="color:#e06c75"&gt;prequel&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;INNER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f_prnt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f_prnt&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;prequel_film_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;prequel_film_id&lt;/span&gt; &lt;span style="color:#c678dd"&gt;IS&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NOT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NULL&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-----------------+--------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;title&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;prequel&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-----------------+--------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FIDDLER&lt;/span&gt; &lt;span style="color:#e06c75"&gt;LOST&lt;/span&gt; &lt;span style="color:#e06c75"&gt;II&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FIDDLER&lt;/span&gt; &lt;span style="color:#e06c75"&gt;LOST&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-----------------+--------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#c678dd"&gt;row&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;00&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;f&lt;/code&gt; representa la película actual y &lt;code&gt;f_prnt&lt;/code&gt; representa la película relacionada como precuela. Los alias son obligatorios para evitar ambigüedad.&lt;/p&gt;
&lt;h2 id="teoría-de-conjuntos"&gt;Teoría de conjuntos&lt;/h2&gt;
&lt;p&gt;SQL también trabaja con conjuntos completos de filas. Estas operaciones combinan resultados de múltiples consultas, siempre que las columnas sean compatibles.&lt;/p&gt;
&lt;p&gt;La unión combina los elementos de &lt;code&gt;A&lt;/code&gt; y &lt;code&gt;B&lt;/code&gt;.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/programming/sql/querying-multiple-tables/set-union_hu_cd19b39dd99e6fc5.webp"
 alt="Imagen guia del contenido de la página"style="width:400px"/&gt;
 &lt;/div&gt;
 
 
 


&lt;p&gt;La intersección conserva únicamente los elementos presentes en ambos conjuntos.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/programming/sql/querying-multiple-tables/set-intersect_hu_8f82de50afd65425.webp"
 alt="Imagen guia del contenido de la página"style="width:400px"/&gt;
 &lt;/div&gt;
 
 
 


&lt;p&gt;La diferencia retorna los elementos de &lt;code&gt;A&lt;/code&gt; que no están en &lt;code&gt;B&lt;/code&gt;.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/programming/sql/querying-multiple-tables/set-except_hu_116968c26251c42f.webp"
 alt="Imagen guia del contenido de la página"style="width:400px"/&gt;
 &lt;/div&gt;
 
 
 






 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Para aplicar operaciones de conjuntos, ambas consultas deben retornar el mismo número de columnas y columnas compatibles por posición.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="union"&gt;UNION&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;UNION&lt;/code&gt; combina resultados y elimina duplicados. &lt;code&gt;UNION ALL&lt;/code&gt; conserva todos los registros, por lo que suele ser más eficiente cuando no necesitas deduplicar.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;CUST&amp;#39;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;typ&lt;/span&gt;, &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;, &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;UNION&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ALL&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;ACTR&amp;#39;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;typ&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;actor&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------+------------+-------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;typ&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------+------------+-------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CUST&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;MARY&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SMITH&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CUST&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;PATRICIA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JOHNSON&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CUST&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;LINDA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;WILLIAMS&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ACTR&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;MARY&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;KEITEL&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ACTR&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JULIA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FAWCETT&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ACTR&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;THORA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;TEMPLE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------+------------+-------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;799&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;00&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Si duplicamos la misma consulta contra &lt;code&gt;actor&lt;/code&gt;, &lt;code&gt;UNION ALL&lt;/code&gt; devuelve dos copias de cada fila.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;ACTR&amp;#39;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;typ&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;actor&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;UNION&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ALL&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;ACTR&amp;#39;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;typ&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;actor&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------+-------------+--------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;typ&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------+-------------+--------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ACTR&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;PENELOPE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;GUINESS&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ACTR&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;NICK&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;WAHLBERG&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ACTR&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ED&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CHASE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ACTR&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;MARY&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;KEITEL&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ACTR&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JULIA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FAWCETT&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ACTR&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;THORA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;TEMPLE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------+-------------+--------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;400&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;00&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Un ejemplo más claro muestra duplicados al combinar clientes y actores con patrones similares:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;, &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#c678dd"&gt;LIKE&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;J%&amp;#39;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;AND&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#c678dd"&gt;LIKE&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;D%&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;UNION&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ALL&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;actor&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#c678dd"&gt;LIKE&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;J%&amp;#39;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;AND&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#c678dd"&gt;LIKE&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;D%&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------------+-----------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------------+-----------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JENNIFER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DAVIS&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JENNIFER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DAVIS&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JUDY&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DEAN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JODIE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DEGENERES&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JULIANNE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DENCH&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------------+-----------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;5&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;00&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="intersect"&gt;INTERSECT&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;INTERSECT&lt;/code&gt; retorna únicamente las filas presentes en ambos conjuntos. Dependiendo del motor, puede existir &lt;code&gt;INTERSECT ALL&lt;/code&gt;, que conserva duplicados según sus reglas.&lt;/p&gt;
&lt;p&gt;Es útil para encontrar coincidencias entre fuentes: identificadores compartidos, productos presentes en dos catálogos o usuarios existentes en dos procesos.&lt;/p&gt;
&lt;h2 id="except"&gt;EXCEPT&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;EXCEPT&lt;/code&gt; retorna las filas del primer conjunto que no aparecen en el segundo. También puede existir &lt;code&gt;EXCEPT ALL&lt;/code&gt;, según el motor.&lt;/p&gt;
&lt;p&gt;Esta operación es práctica para auditoría y reconciliación de datos.&lt;/p&gt;




 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Algunos motores no implementan &lt;code&gt;INTERSECT&lt;/code&gt;, &lt;code&gt;EXCEPT&lt;/code&gt; o sus variantes &lt;code&gt;ALL&lt;/code&gt;. En esos casos puedes modelar equivalentes con &lt;code&gt;JOIN&lt;/code&gt;, &lt;code&gt;NOT EXISTS&lt;/code&gt; o &lt;code&gt;LEFT JOIN&lt;/code&gt;.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="reglas-de-operaciones-de-conjuntos"&gt;Reglas de operaciones de conjuntos&lt;/h2&gt;
&lt;p&gt;Las operaciones de conjuntos son estrictas: mismo número de columnas, tipos compatibles y mismo orden.&lt;/p&gt;
&lt;h3 id="ordenar-resultados-con-alias-válidos"&gt;Ordenar resultados con alias válidos&lt;/h3&gt;
&lt;p&gt;Si ordenas el resultado final, usa los nombres expuestos por el primer &lt;code&gt;SELECT&lt;/code&gt;. En este ejemplo, &lt;code&gt;last_name&lt;/code&gt; y &lt;code&gt;first_name&lt;/code&gt; ya no son etiquetas válidas porque fueron renombradas como &lt;code&gt;lname&lt;/code&gt; y &lt;code&gt;fname&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;-- ERROR
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fname&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#e06c75"&gt;lname&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;actor&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#c678dd"&gt;LIKE&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;J%&amp;#39;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;AND&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#c678dd"&gt;LIKE&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;D%&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;UNION&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ALL&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;, &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#c678dd"&gt;LIKE&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;J%&amp;#39;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;AND&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#c678dd"&gt;LIKE&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;D%&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ORDER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;BY&lt;/span&gt; &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;ERROR&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1054&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;42&lt;/span&gt;&lt;span style="color:#e06c75"&gt;S22&lt;/span&gt;): &lt;span style="color:#c678dd"&gt;Unknown&lt;/span&gt; &lt;span style="color:#c678dd"&gt;column&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;last_name&amp;#39;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;order clause&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;-- WORKS
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fname&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#e06c75"&gt;lname&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;actor&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#c678dd"&gt;LIKE&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;J%&amp;#39;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;AND&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#c678dd"&gt;LIKE&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;D%&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;UNION&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ALL&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;, &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#c678dd"&gt;LIKE&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;J%&amp;#39;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;AND&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#c678dd"&gt;LIKE&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;D%&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ORDER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;BY&lt;/span&gt; &lt;span style="color:#e06c75"&gt;lname&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;fname&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;----------+-----------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fname&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;lname&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;----------+-----------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JENNIFER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DAVIS&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JENNIFER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DAVIS&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JUDY&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DEAN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JODIE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DEGENERES&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JULIANNE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DENCH&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;----------+-----------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;5&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;00&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="el-orden-de-las-operaciones-importa"&gt;El orden de las operaciones importa&lt;/h3&gt;
&lt;p&gt;Las uniones se evalúan según el orden y la precedencia del motor. Cuando mezcles &lt;code&gt;UNION&lt;/code&gt;, &lt;code&gt;INTERSECT&lt;/code&gt; y &lt;code&gt;EXCEPT&lt;/code&gt;, usa paréntesis para expresar intención y evitar resultados ambiguos.&lt;/p&gt;
&lt;p&gt;Reglas prácticas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Los alias visibles provienen del primer &lt;code&gt;SELECT&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;UNION&lt;/code&gt; elimina duplicados; &lt;code&gt;UNION ALL&lt;/code&gt; los conserva.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ORDER BY&lt;/code&gt; se aplica al conjunto final, salvo que uses subqueries.&lt;/li&gt;
&lt;li&gt;El orden de operaciones puede cambiar el resultado.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="cierre"&gt;Cierre&lt;/h2&gt;
&lt;p&gt;Los &lt;code&gt;JOINs&lt;/code&gt; y las operaciones de conjuntos resuelven problemas complementarios. &lt;code&gt;INNER JOIN&lt;/code&gt; conecta filas relacionadas; &lt;code&gt;UNION&lt;/code&gt;, &lt;code&gt;INTERSECT&lt;/code&gt; y &lt;code&gt;EXCEPT&lt;/code&gt; combinan resultados compatibles.&lt;/p&gt;
&lt;p&gt;Dominar ambos enfoques mejora la semántica de reportes, filtros e integraciones. En el siguiente artículo avanzaremos hacia &lt;a href="https://blog.dacadev.com/programacion/sql/06-subqueries-subconsultas"



 


&gt;Subqueries&lt;/a&gt;, donde veremos subconsultas para construir lógica SQL modular.&lt;/p&gt;</content:encoded></item><item><title>TypeScript: Funciones, parámetros y generadores</title><link>https://blog.dacadev.com/typescript/funciones/</link><pubDate>Wed, 17 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/typescript/funciones/</guid><dc:creator>Dacadev</dc:creator><category>programación</category><description>Aprende a tipar funciones en TypeScript: tipos de retorno, parámetros opcionales y por defecto, operador resto, call signatures, generadores e iteradores.</description><media:content url="https://blog.dacadev.com/images/typescript/functions/banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#declaración-y-tipado-de-funciones"&gt;Declaración y tipado de funciones&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#parámetros-opcionales-y-por-defecto"&gt;Parámetros opcionales y por defecto&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#operador-resto-funciones-variádicas"&gt;Operador resto: funciones variádicas&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#call-apply-y-bind"&gt;call, apply y bind&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#generadores"&gt;Generadores&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#iteradores"&gt;Iteradores&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#call-signatures"&gt;Call signatures&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#conclusión"&gt;Conclusión&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;





 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Cuarto artículo de la serie sobre &lt;strong&gt;TypeScript&lt;/strong&gt;. Cubriremos el tipado de funciones: parámetros, tipos de retorno, parámetros opcionales y por defecto, el operador resto, &lt;em&gt;call signatures&lt;/em&gt;, generadores e iteradores.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Las funciones son el núcleo de cualquier base de código, y es justo donde el tipado aporta más valor: una firma bien tipada documenta el contrato de entrada y salida, y convierte cualquier llamada inválida en un error de compilación. Analicemos cómo TypeScript modela las &lt;strong&gt;funciones&lt;/strong&gt; en toda su variedad.&lt;/p&gt;
&lt;h2 id="declaración-y-tipado-de-funciones"&gt;Declaración y tipado de funciones&lt;/h2&gt;
&lt;p&gt;Una función tipada declara el tipo de cada parámetro y, opcionalmente, el tipo de retorno:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;function&lt;/span&gt; &lt;span style="color:#e06c75"&gt;add&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;a&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;b&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;+&lt;/span&gt; &lt;span style="color:#e06c75"&gt;b&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;TypeScript admite todas las formas de definir funciones de JavaScript, y a todas les aplica el mismo sistema de tipos:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// Named function
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;function&lt;/span&gt; &lt;span style="color:#e06c75"&gt;greet&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;hello &amp;#39;&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;+&lt;/span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// Function expression
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;greet2&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#c678dd"&gt;function&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;hello &amp;#39;&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;+&lt;/span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// Arrow function
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;greet3&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;hello &amp;#39;&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;+&lt;/span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// Shorthand arrow function
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;greet4&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;hello &amp;#39;&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;+&lt;/span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El tipado de los parámetros intercepta llamadas inválidas en el sitio exacto del error:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;add&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;// Error TS2554: se esperaban 2 argumentos, se recibió 1.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;add&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;a&amp;#39;&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;// Error TS2345: &amp;#39;string&amp;#39; no es asignable a &amp;#39;number&amp;#39;.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="parámetros-opcionales-y-por-defecto"&gt;Parámetros opcionales y por defecto&lt;/h2&gt;
&lt;p&gt;Un parámetro opcional se marca con &lt;code&gt;?&lt;/code&gt; y debe gestionarse dentro del cuerpo, ya que puede llegar como &lt;code&gt;undefined&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;function&lt;/span&gt; &lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;message&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;userId?&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;time&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#c678dd"&gt;new&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;Date&lt;/span&gt;().&lt;span style="color:#e06c75"&gt;toLocaleTimeString&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;time&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;message&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;userId&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;||&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Not signed in&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;Page loaded&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;User signed in&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;da763be&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Un parámetro con valor por defecto se vuelve opcional automáticamente, y TypeScript infiere su tipo a partir del valor asignado:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;function&lt;/span&gt; &lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;message&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;userId&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Not signed in&amp;#39;&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;time&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#c678dd"&gt;new&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;Date&lt;/span&gt;().&lt;span style="color:#e06c75"&gt;toISOString&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;time&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;message&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;userId&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Los parámetros opcionales deben ubicarse &lt;strong&gt;después&lt;/strong&gt; de todos los obligatorios, y no pueden combinarse con el operador resto.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;También puedes apoyarte en un &lt;code&gt;type&lt;/code&gt; para estructurar parámetros de configuración:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;type&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Context&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;appId?&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;userId?&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;function&lt;/span&gt; &lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;message&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;context&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;Context&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; {}) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;time&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#c678dd"&gt;new&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;Date&lt;/span&gt;().&lt;span style="color:#e06c75"&gt;toISOString&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;time&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;message&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;context&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;userId&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="operador-resto-funciones-variádicas"&gt;Operador resto: funciones variádicas&lt;/h2&gt;
&lt;p&gt;El operador resto captura un número dinámico de argumentos en un arreglo tipado, lo que produce firmas más legibles que recibir un arreglo explícito:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// Recibe un arreglo
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;function&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sum&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;numbers&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;[])&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;numbers&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;reduce&lt;/span&gt;((&lt;span style="color:#e06c75"&gt;total&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;n&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;total&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;+&lt;/span&gt; &lt;span style="color:#e06c75"&gt;n&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;sum&lt;/span&gt;([&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;2&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;]) &lt;span style="color:#7f848e"&gt;// 6
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// Variádica con operador resto
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;function&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sumVariadicSafe&lt;/span&gt;(...&lt;span style="color:#e06c75"&gt;numbers&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;[])&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;numbers&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;reduce&lt;/span&gt;((&lt;span style="color:#e06c75"&gt;total&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;n&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;total&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;+&lt;/span&gt; &lt;span style="color:#e06c75"&gt;n&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;sumVariadicSafe&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;2&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;// 6
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="call-apply-y-bind"&gt;call, apply y bind&lt;/h2&gt;
&lt;p&gt;TypeScript respeta los mecanismos clásicos de invocación de JavaScript, aplicando la verificación de tipos a sus argumentos:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;function&lt;/span&gt; &lt;span style="color:#e06c75"&gt;add&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;a&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;b&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;+&lt;/span&gt; &lt;span style="color:#e06c75"&gt;b&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;add&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;10&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;20&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;// 30
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;add&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;apply&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;null&lt;/span&gt;, [&lt;span style="color:#d19a66"&gt;10&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;20&lt;/span&gt;]) &lt;span style="color:#7f848e"&gt;// 30
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;add&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;call&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;null&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;10&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;20&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;// 30
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;add&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;bind&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;null&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;10&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;20&lt;/span&gt;)() &lt;span style="color:#7f848e"&gt;// 30
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="generadores"&gt;Generadores&lt;/h2&gt;
&lt;p&gt;Los generadores producen valores bajo demanda. Se declaran con un asterisco tras &lt;code&gt;function&lt;/code&gt; y emiten valores con &lt;code&gt;yield&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;function&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;*&lt;/span&gt; &lt;span style="color:#e06c75"&gt;createFibonacciGenerator() {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;b&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;while&lt;/span&gt; (&lt;span style="color:#e5c07b"&gt;true&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;yield&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ;[&lt;span style="color:#e06c75"&gt;a&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;b&lt;/span&gt;] &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; [&lt;span style="color:#e06c75"&gt;b&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;a&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;+&lt;/span&gt; &lt;span style="color:#e06c75"&gt;b&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fib&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;createFibonacciGenerator&lt;/span&gt;() &lt;span style="color:#7f848e"&gt;// IterableIterator&amp;lt;number&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;fib&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;next&lt;/span&gt;() &lt;span style="color:#7f848e"&gt;// { value: 0, done: false }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;fib&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;next&lt;/span&gt;() &lt;span style="color:#7f848e"&gt;// { value: 1, done: false }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;fib&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;next&lt;/span&gt;() &lt;span style="color:#7f848e"&gt;// { value: 1, done: false }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;fib&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;next&lt;/span&gt;() &lt;span style="color:#7f848e"&gt;// { value: 2, done: false }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El método &lt;code&gt;next()&lt;/code&gt; extrae el siguiente valor de la secuencia. TypeScript infiere el tipo &lt;code&gt;IterableIterator&amp;lt;number&amp;gt;&lt;/code&gt; a partir de lo que produce &lt;code&gt;yield&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="iteradores"&gt;Iteradores&lt;/h2&gt;
&lt;p&gt;Un iterador se define implementando el método &lt;code&gt;[Symbol.iterator]&lt;/code&gt;. TypeScript es capaz de reconocer la estructura y tiparla correctamente:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;numbers&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;*&lt;/span&gt;[&lt;span style="color:#e06c75"&gt;Symbol&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;iterator&lt;/span&gt;]() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;for&lt;/span&gt; (&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;n&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;; &lt;span style="color:#e06c75"&gt;n&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;&amp;lt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;10&lt;/span&gt;; &lt;span style="color:#e06c75"&gt;n&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;yield&lt;/span&gt; &lt;span style="color:#e06c75"&gt;n&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="call-signatures"&gt;Call signatures&lt;/h2&gt;
&lt;p&gt;Una &lt;em&gt;call signature&lt;/em&gt; describe el tipo de una función de forma independiente a su implementación. Para la siguiente función:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;function&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sum&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;a&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;b&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;+&lt;/span&gt; &lt;span style="color:#e06c75"&gt;b&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;su firma de llamada se expresa así:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;(&lt;span style="color:#e06c75"&gt;a&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;b&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El tipo genérico &lt;code&gt;Function&lt;/code&gt; es un comodín que no aporta información sobre la firma concreta; las &lt;em&gt;call signatures&lt;/em&gt; permiten tipar funciones con precisión. Además, cuando una función puede retornar varios tipos, cada uno debe tratarse para satisfacer al typechecker:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;function&lt;/span&gt; &lt;span style="color:#e06c75"&gt;area&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;radius&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;null&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;if&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;radius&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;Math&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;PI&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;*&lt;/span&gt; &lt;span style="color:#e06c75"&gt;radius&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;**&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;area&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;3&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;if&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;a&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;!==&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;null&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;info&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;result:&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;// dentro del guard, a es number
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;El tipado de funciones convierte cada firma en un contrato verificable: parámetros opcionales y por defecto modelan flexibilidad controlada, el operador resto expresa funciones variádicas con claridad, las &lt;em&gt;call signatures&lt;/em&gt; tipan funciones como ciudadanos de primera clase, y los generadores e iteradores se integran sin fricción en el sistema de tipos.&lt;/p&gt;
&lt;p&gt;En el siguiente artículo abordaremos las &lt;strong&gt;interfaces&lt;/strong&gt;, el mecanismo de TypeScript para definir contratos extensibles.&lt;/p&gt;</content:encoded></item><item><title>Estilos CSS: Modularización y patrones de diseño</title><link>https://blog.dacadev.com/programacion/estilos-css/modularizacion-y-patrones/</link><pubDate>Tue, 16 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/programacion/estilos-css/modularizacion-y-patrones/</guid><dc:creator>Dacadev</dc:creator><category>programación</category><description>Aprende a organizar CSS a escala: estilos base, componentes modulares, la metodología BEM, clases de utilidad y la documentación con librerías de patrones.</description><media:content url="https://blog.dacadev.com/images/programming/html-and-css/css/08-modularizacion-y-patrones-banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#qué-es-la-modularización"&gt;Qué es la modularización&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#estilos-base"&gt;Estilos base&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#componentes-y-bem"&gt;Componentes y BEM&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#posicionamiento-del-componente"&gt;Posicionamiento del componente&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#estado-de-los-componentes"&gt;Estado de los componentes&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#utility-classes"&gt;Utility classes&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#metodologías-de-arquitectura-css"&gt;Metodologías de arquitectura CSS&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#librerías-de-patrones"&gt;Librerías de patrones&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#conclusión"&gt;Conclusión&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;p&gt;En un proyecto pequeño cualquier organización de CSS funciona. El problema aparece al escalar: hojas de estilo de miles de líneas donde tocar una regla rompe tres componentes que parecían no tener relación. La causa casi siempre es la misma: estilos acoplados que se pisan entre sí. La solución es arquitectónica —modularizar— y existen metodologías probadas para lograrlo.&lt;/p&gt;
&lt;p&gt;Esta es la octava y última entrega de la serie &lt;strong&gt;Estilos CSS&lt;/strong&gt;. Veremos cómo estructurar estilos en módulos independientes, la metodología &lt;strong&gt;BEM&lt;/strong&gt;, las clases de utilidad y cómo documentar tus componentes con una librería de patrones.&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Aprenderás a dividir tus estilos en componentes desacoplados, a nombrar clases con BEM, a usar utility classes con criterio y a mantener una librería de patrones como fuente única de verdad del diseño.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="qué-es-la-modularización"&gt;Qué es la modularización&lt;/h2&gt;
&lt;p&gt;Modularizar CSS consiste en dividir los estilos en archivos donde cada uno representa un &lt;strong&gt;módulo&lt;/strong&gt;: un único componente con todo su estilo encapsulado. Un módulo &lt;code&gt;button.css&lt;/code&gt; contiene todo lo necesario para renderizar un botón y sus variantes, y nada más.&lt;/p&gt;




 
 





 


&lt;div class="notice tip"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z" /&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Tip&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;La regla de oro: un módulo no debe interferir con los estilos de otros. Solo se ocupa de su propio componente. Así, modificar un módulo nunca produce efectos colaterales inesperados en el resto de la página.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="estilos-base"&gt;Estilos base&lt;/h2&gt;
&lt;p&gt;Antes de los módulos conviene tener un archivo de &lt;strong&gt;estilos base&lt;/strong&gt;: no es un componente, sino la configuración inicial del documento (reset, tipografía global, &lt;code&gt;box-sizing&lt;/code&gt;).&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;:&lt;span style="color:#61afef"&gt;root&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;box-sizing&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;border-box&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;*,&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;*&lt;/span&gt;::&lt;span style="color:#61afef"&gt;before&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;,&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;*&lt;/span&gt;::&lt;span style="color:#61afef"&gt;after&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;box-sizing&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;inherit&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;body&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;font-family&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;Helvetica&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;Arial&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;sans-serif&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Para no reinventar la rueda, paquetes como &lt;a href="https://necolas.github.io/normalize.css/"




 target="_blank"
 


&gt;Normalize.css&lt;/a&gt; homogeneizan las diferencias entre navegadores de forma sensata.&lt;/p&gt;
&lt;h2 id="componentes-y-bem"&gt;Componentes y BEM&lt;/h2&gt;
&lt;p&gt;La idea central de un módulo es que los estilos y modificadores de un componente vivan en un solo lugar. La metodología &lt;strong&gt;BEM&lt;/strong&gt; (&lt;em&gt;Block, Element, Modifier&lt;/em&gt;) propone una convención de nombres que hace explícita la estructura y evita colisiones:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Block&lt;/strong&gt; — el componente raíz: &lt;code&gt;.button&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Element&lt;/strong&gt; — una parte del componente, con &lt;code&gt;__&lt;/code&gt;: &lt;code&gt;.button__icon&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Modifier&lt;/strong&gt; — una variante, con &lt;code&gt;--&lt;/code&gt;: &lt;code&gt;.button--success&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;button&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;padding&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;0.5&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;em&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0.8&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;em&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;border&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;px&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;solid&lt;/span&gt; &lt;span style="color:#d19a66"&gt;#265559&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;border-radius&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;0.2&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;em&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;background-color&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;transparent&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;font-size&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;rem&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;button--success&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;color&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;#fff&lt;/span&gt;; &lt;span style="color:#c678dd"&gt;background-color&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;#2f5926&lt;/span&gt;; &lt;span style="color:#c678dd"&gt;border-color&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;#cfe8c9&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;button--danger&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;color&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;#fff&lt;/span&gt;; &lt;span style="color:#c678dd"&gt;background-color&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;#a92323&lt;/span&gt;; &lt;span style="color:#c678dd"&gt;border-color&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;#e8c9c9&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;button--small&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;font-size&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;0.8&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;rem&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;button--large&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;font-size&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;1.2&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;rem&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;button&lt;/span&gt; &lt;span style="color:#e06c75"&gt;class&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#34;button&amp;#34;&lt;/span&gt;&amp;gt;Normal&amp;lt;/&lt;span style="color:#e06c75"&gt;button&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;button&lt;/span&gt; &lt;span style="color:#e06c75"&gt;class&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#34;button button--success&amp;#34;&lt;/span&gt;&amp;gt;Éxito&amp;lt;/&lt;span style="color:#e06c75"&gt;button&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;button&lt;/span&gt; &lt;span style="color:#e06c75"&gt;class&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#34;button button--danger&amp;#34;&lt;/span&gt;&amp;gt;Peligro&amp;lt;/&lt;span style="color:#e06c75"&gt;button&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;button&lt;/span&gt; &lt;span style="color:#e06c75"&gt;class&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#34;button button--large&amp;#34;&lt;/span&gt;&amp;gt;Grande&amp;lt;/&lt;span style="color:#e06c75"&gt;button&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border:1px solid #d0d0d0;border-radius:.5rem;padding:1.5rem;background:#fff;margin:1rem 0;font-family:Helvetica,Arial,sans-serif;display:flex;gap:.75rem;flex-wrap:wrap;align-items:center;"&gt;
 &lt;button type="button" style="padding:.5em .8em;border:1px solid #265559;border-radius:.2em;background:transparent;font-size:1rem;color:#265559;cursor:pointer;"&gt;Normal&lt;/button&gt;
 &lt;button type="button" style="padding:.5em .8em;border:1px solid #cfe8c9;border-radius:.2em;background:#2f5926;font-size:1rem;color:#fff;cursor:pointer;"&gt;Éxito&lt;/button&gt;
 &lt;button type="button" style="padding:.5em .8em;border:1px solid #e8c9c9;border-radius:.2em;background:#a92323;font-size:1rem;color:#fff;cursor:pointer;"&gt;Peligro&lt;/button&gt;
 &lt;button type="button" style="padding:.5em .8em;border:1px solid #265559;border-radius:.2em;background:transparent;font-size:1.2rem;color:#265559;cursor:pointer;"&gt;Grande&lt;/button&gt;
&lt;/div&gt;
&lt;h3 id="posicionamiento-del-componente"&gt;Posicionamiento del componente&lt;/h3&gt;
&lt;p&gt;Por buena práctica, el bloque raíz de un componente debería declarar &lt;code&gt;position: relative&lt;/code&gt;. Así estableces un contexto de posicionamiento controlado para cualquier elemento absoluto interno (un menú desplegable, un badge, un tooltip), sin depender de ancestros externos.&lt;/p&gt;
&lt;h3 id="estado-de-los-componentes"&gt;Estado de los componentes&lt;/h3&gt;
&lt;p&gt;Es común reflejar el estado de un componente con clases, ya sea para estilizarlo o para manipularlo desde JavaScript. La convención recomendada usa verbos o estados con prefijo: &lt;code&gt;is-loading&lt;/code&gt;, &lt;code&gt;has-error&lt;/code&gt;, &lt;code&gt;is-active&lt;/code&gt;.&lt;/p&gt;




 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;No mezcles las clases de estado con los modificadores BEM. Evita nombres como &lt;code&gt;block__element--modifier-is-loading&lt;/code&gt;. El estado es una capa transversal y dinámica; mantenlo separado de la variante estática del componente.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="utility-classes"&gt;Utility classes&lt;/h2&gt;
&lt;p&gt;Las &lt;strong&gt;clases de utilidad&lt;/strong&gt; aplican un estilo único y específico. Suelen usar &lt;code&gt;!important&lt;/code&gt; para garantizar que se apliquen por encima de los estilos del componente:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;text-center&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;text-align&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;center&lt;/span&gt; &lt;span style="color:#7f848e"&gt;!important&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;float-left&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;float&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;left&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;hidden&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;display&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;none&lt;/span&gt; &lt;span style="color:#7f848e"&gt;!important&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;clearfix&lt;/span&gt;::&lt;span style="color:#61afef"&gt;before&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;clearfix&lt;/span&gt;::&lt;span style="color:#61afef"&gt;after&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;content&lt;/span&gt;: &lt;span style="color:#98c379"&gt;&amp;#34; &amp;#34;&lt;/span&gt;; &lt;span style="color:#c678dd"&gt;display&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;table&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;clearfix&lt;/span&gt;::&lt;span style="color:#61afef"&gt;after&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;clear&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;both&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Son útiles para ajustes puntuales, pero abusar de ellas reintroduce el acoplamiento que la modularización busca evitar. Úsalas con criterio.&lt;/p&gt;
&lt;h2 id="metodologías-de-arquitectura-css"&gt;Metodologías de arquitectura CSS&lt;/h2&gt;
&lt;p&gt;BEM no es la única opción. Las metodologías más establecidas para organizar CSS a escala son:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;OOCSS&lt;/strong&gt; — &lt;em&gt;Object-Oriented CSS&lt;/em&gt;, de Nicole Sullivan: separa estructura de apariencia.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SMACSS&lt;/strong&gt; — &lt;em&gt;Scalable and Modular Architecture for CSS&lt;/em&gt;, de Jonathan Snook: categoriza las reglas en capas.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;BEM&lt;/strong&gt; — &lt;em&gt;Block, Element, Modifier&lt;/em&gt;, de Yandex: convención de nombres explícita.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ITCSS&lt;/strong&gt; — &lt;em&gt;Inverted Triangle CSS&lt;/em&gt;, de Harry Roberts: organiza por especificidad creciente.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;No son excluyentes; muchos equipos combinan ITCSS para la estructura de archivos con BEM para la nomenclatura.&lt;/p&gt;
&lt;h2 id="librerías-de-patrones"&gt;Librerías de patrones&lt;/h2&gt;
&lt;p&gt;En proyectos grandes, los componentes se documentan en una &lt;strong&gt;librería de patrones&lt;/strong&gt; (o &lt;em&gt;style guide&lt;/em&gt;): una web accesible para todo el equipo que muestra cómo se ve y se comporta cada componente. Es la fuente única de verdad del diseño y reduce las inconsistencias.&lt;/p&gt;
&lt;p&gt;Existen generadores de style guides; uno open source muy conocido es &lt;a href="https://kss-node.github.io/kss-node/"




 target="_blank"
 


&gt;KSS&lt;/a&gt;. Documenta los componentes a partir de comentarios estructurados en el propio CSS:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;/*
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;Buttons
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;Botones disponibles en varios tamaños y colores.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;Markup:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;&amp;lt;button class=&amp;#34;button {{modifier_class}}&amp;#34;&amp;gt;click here&amp;lt;/button&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;.button--success - Botón verde de éxito
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;.button--danger - Botón rojo de peligro
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;.button--large - Botón grande
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;Styleguide Buttons
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;*/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;button&lt;/span&gt; { &lt;span style="color:#7f848e"&gt;/* ... */&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;KSS lee esos comentarios y genera automáticamente una página de documentación con el componente renderizado y todas sus variantes. El bloque incluye un título, una descripción, el &lt;code&gt;Markup&lt;/code&gt; de ejemplo (con el marcador &lt;code&gt;{{modifier_class}}&lt;/code&gt;), la lista de modificadores y una referencia &lt;code&gt;Styleguide&lt;/code&gt; para ubicarlo en la jerarquía.&lt;/p&gt;




 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Mantener la documentación junto al código —en comentarios del propio CSS— reduce el riesgo de que la librería de patrones quede desactualizada respecto a la implementación real.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;Escribir CSS que escale es, ante todo, un problema de arquitectura. Modularizar en componentes desacoplados, nombrar con una convención consistente como BEM, reservar las utility classes para ajustes puntuales y documentar todo en una librería de patrones es lo que mantiene una hoja de estilos sana a medida que el proyecto crece.&lt;/p&gt;
&lt;p&gt;Con esta entrega cerramos la serie &lt;strong&gt;Estilos CSS&lt;/strong&gt;. Recorrimos desde los fundamentos de la cascada hasta la arquitectura de estilos a gran escala, pasando por selectores, el modelo de caja, layouts, posicionamiento, fondos y animaciones. Tienes ahora un modelo mental completo para escribir CSS profesional, predecible y mantenible.&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;🚀 Repasa las entregas anteriores para consolidar cada concepto: los fundamentos sostienen los selectores, el modelo de caja sostiene los layouts, y la modularización une todo en un sistema coherente.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
</content:encoded></item><item><title>TypeScript: Objetos y tipos personalizados</title><link>https://blog.dacadev.com/typescript/objetos-y-tipos-personalizados/</link><pubDate>Tue, 16 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/typescript/objetos-y-tipos-personalizados/</guid><dc:creator>Dacadev</dc:creator><category>programación</category><description>Aprende a tipar objetos literales en TypeScript, definir tipos personalizados con type, usar campos opcionales y métodos, y permitir múltiples tipos con uniones.</description><media:content url="https://blog.dacadev.com/images/typescript/objects-custom-types/banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#objetos-literales-y-la-inferencia-estructural"&gt;Objetos literales y la inferencia estructural&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#tipar-objetos-de-forma-inline"&gt;Tipar objetos de forma inline&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#tipos-personalizados-con-type"&gt;Tipos personalizados con type&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#permitir-múltiples-tipos-con-uniones"&gt;Permitir múltiples tipos con uniones&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#conclusión"&gt;Conclusión&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;





 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Tercer artículo de la serie sobre &lt;strong&gt;TypeScript&lt;/strong&gt;. Diseñaremos la forma de nuestros objetos con tipos personalizados, definiremos campos opcionales y métodos, y permitiremos que una variable acepte múltiples tipos.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Modelar correctamente la estructura de los objetos es donde TypeScript empieza a pagar dividendos en proyectos reales. Un &lt;strong&gt;tipo personalizado&lt;/strong&gt; bien diseñado centraliza la definición de una entidad, propaga su forma por todo el código y convierte cualquier desviación en un error de compilación. Analicemos cómo pasar de objetos literales sueltos a un modelo de tipos mantenible.&lt;/p&gt;
&lt;h2 id="objetos-literales-y-la-inferencia-estructural"&gt;Objetos literales y la inferencia estructural&lt;/h2&gt;
&lt;p&gt;Los objetos literales funcionan igual que en JavaScript, pero TypeScript infiere automáticamente su estructura. Esa inferencia es justamente lo que impide reasignar un objeto con una forma distinta:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;flash&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Barry Allen&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;age&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;24&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;powers&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; [&lt;span style="color:#98c379"&gt;&amp;#39;super velocidad&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;viajar en el tiempo&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;flash&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;name2&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Otro nombre&amp;#39;&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// Error: el literal solo puede especificar propiedades conocidas;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// &amp;#39;name2&amp;#39; no existe en el tipo inferido y faltan &amp;#39;name&amp;#39;, &amp;#39;age&amp;#39;, &amp;#39;powers&amp;#39;.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;TypeScript bloquea la reasignación porque el nuevo literal no respeta la forma deducida de &lt;code&gt;flash&lt;/code&gt;. Este comportamiento evita introducir campos accidentales o incompletos.&lt;/p&gt;
&lt;h2 id="tipar-objetos-de-forma-inline"&gt;Tipar objetos de forma inline&lt;/h2&gt;
&lt;p&gt;Podemos declarar explícitamente la forma del objeto usando la misma sintaxis de anotación que venimos aplicando, incluyendo campos opcionales con &lt;code&gt;?&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;flash&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;age?&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;powers&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;[] } &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Barry Allen&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;age&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;24&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;powers&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; [&lt;span style="color:#98c379"&gt;&amp;#39;super velocidad&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;viajar en el tiempo&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;flash&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Clark Kent&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;powers&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; [&lt;span style="color:#98c379"&gt;&amp;#39;volar&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;rayo láser&amp;#39;&lt;/span&gt;] &lt;span style="color:#7f848e"&gt;// &amp;#39;age&amp;#39; es opcional, puede omitirse
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;La posición de un campo opcional dentro de la anotación es irrelevante. &lt;code&gt;age?&lt;/code&gt; puede ir en medio de la definición sin afectar la validez de los objetos que lo omitan.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;El problema de este enfoque &lt;em&gt;inline&lt;/em&gt; es la duplicación: si dos variables deben compartir la misma forma, hay que repetir la anotación completa en cada una y mantenerlas sincronizadas manualmente. Esto no escala.&lt;/p&gt;
&lt;h2 id="tipos-personalizados-con-type"&gt;Tipos personalizados con type&lt;/h2&gt;
&lt;p&gt;La solución es definir la estructura una sola vez con la palabra clave &lt;code&gt;type&lt;/code&gt; y reutilizarla en todo el código. Esto centraliza el modelo en un único punto de verdad:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;type&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Hero&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;age?&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;powers&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;[];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;getName&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;?:&lt;/span&gt; () &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;flash&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;Hero&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Barry Allen&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;age&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;24&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;powers&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; [&lt;span style="color:#98c379"&gt;&amp;#39;super velocidad&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;viajar en el tiempo&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;superman&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;Hero&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Clark Kent&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;age&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;30&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;powers&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; [&lt;span style="color:#98c379"&gt;&amp;#39;volar&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;rayo láser&amp;#39;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;getName() {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#c678dd"&gt;this&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;name&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El tipo &lt;code&gt;Hero&lt;/code&gt; declara &lt;code&gt;name&lt;/code&gt; y &lt;code&gt;powers&lt;/code&gt; como obligatorios, &lt;code&gt;age&lt;/code&gt; como opcional y &lt;code&gt;getName&lt;/code&gt; como un &lt;strong&gt;método opcional&lt;/strong&gt; cuya firma es &lt;code&gt;() =&amp;gt; string&lt;/code&gt;. Cualquier objeto anotado con &lt;code&gt;Hero&lt;/code&gt; debe respetar este contrato, y un solo cambio en la definición se propaga a todas las variables que lo usan.&lt;/p&gt;
&lt;pre class="mermaid"&gt;flowchart TD
 T[type Hero] --&amp;gt; A[flash: Hero]
 T --&amp;gt; B[superman: Hero]
 T --&amp;gt; C[...otros héroes]
 note[&amp;#34;Un cambio en Hero&amp;lt;br/&amp;gt;se propaga a todos&amp;#34;] -.-&amp;gt; T
&lt;/pre&gt;





 
 





 


&lt;div class="notice tip"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z" /&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Tip&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Define un &lt;code&gt;type&lt;/code&gt; para toda entidad que aparezca más de una vez. La regla práctica: si copiarías la anotación inline por segunda vez, conviértela en un tipo personalizado.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="permitir-múltiples-tipos-con-uniones"&gt;Permitir múltiples tipos con uniones&lt;/h2&gt;
&lt;p&gt;Una variable puede aceptar más de un tipo mediante el operador de unión &lt;code&gt;|&lt;/code&gt;. Esto resulta útil para valores que legítimamente cambian de forma según el contexto:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;type&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Hero&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;age?&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;powers&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;[];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;getName&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;?:&lt;/span&gt; () &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;myCustomVariable&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;Hero&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;¡Hola mundo!&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;myCustomVariable&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;42&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// válido: number
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;myCustomVariable&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; { &lt;span style="color:#7f848e"&gt;// válido: Hero
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Diana&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;powers&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; [&lt;span style="color:#98c379"&gt;&amp;#39;fuerza sobrehumana&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;myCustomVariable&lt;/code&gt; puede contener un &lt;code&gt;Hero&lt;/code&gt;, un &lt;code&gt;string&lt;/code&gt; o un &lt;code&gt;number&lt;/code&gt;. El typechecker permitirá únicamente operaciones válidas para todos los miembros de la unión hasta que acotes el tipo con un &lt;em&gt;type guard&lt;/em&gt; (por ejemplo, &lt;code&gt;typeof&lt;/code&gt; o una comprobación de propiedad).&lt;/p&gt;
&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;Pasar de objetos literales inline a tipos personalizados con &lt;code&gt;type&lt;/code&gt; es el salto que transforma TypeScript de una simple validación a una herramienta de diseño. Un tipo centraliza la forma de una entidad, los campos opcionales modelan la realidad de los datos incompletos, los métodos definen comportamiento esperado y las uniones aportan flexibilidad controlada.&lt;/p&gt;
&lt;p&gt;En el próximo artículo de la serie abordaremos las &lt;strong&gt;funciones&lt;/strong&gt;: anotación de parámetros, tipos de retorno, parámetros opcionales y sobrecargas.&lt;/p&gt;</content:encoded></item><item><title>TypeScript: Tipos básicos y el sistema de tipos</title><link>https://blog.dacadev.com/typescript/tipos-basicos/</link><pubDate>Mon, 15 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/typescript/tipos-basicos/</guid><dc:creator>Dacadev</dc:creator><category>programación</category><description>Domina los tipos básicos de TypeScript: any, unknown, boolean, number, bigint, string, symbol, objetos, alias, uniones, intersecciones, arreglos y tuplas.</description><media:content url="https://blog.dacadev.com/images/typescript/basic-types/banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#por-qué-importan-los-tipos-un-ejemplo-concreto"&gt;Por qué importan los tipos: un ejemplo concreto&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#any-la-puerta-de-escape-del-sistema-de-tipos"&gt;any: la puerta de escape del sistema de tipos&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#unknown-la-alternativa-segura-a-any"&gt;unknown: la alternativa segura a any&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#boolean"&gt;boolean&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#number-y-bigint"&gt;number y bigint&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#string"&gt;string&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#symbol"&gt;symbol&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#objetos"&gt;Objetos&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#alias-de-tipo"&gt;Alias de tipo&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#tipos-unión-e-intersección"&gt;Tipos unión e intersección&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#arreglos"&gt;Arreglos&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#tuplas"&gt;Tuplas&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#conclusión"&gt;Conclusión&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;





 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Segundo artículo de la serie sobre &lt;strong&gt;TypeScript&lt;/strong&gt;. Recorreremos el alfabeto de tipos del lenguaje: desde &lt;code&gt;any&lt;/code&gt; y &lt;code&gt;unknown&lt;/code&gt; hasta uniones, intersecciones, tuplas y alias de tipo.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Cuando el typechecker sabe que un valor es de tipo &lt;code&gt;T&lt;/code&gt;, no solo conoce su naturaleza: también sabe &lt;strong&gt;exactamente qué operaciones son válidas&lt;/strong&gt; sobre ese valor y cuáles no. Ese es el propósito del sistema de tipos. Comprender el catálogo de &lt;strong&gt;tipos básicos en TypeScript&lt;/strong&gt; es la base sobre la que se construye todo lo demás, así que dediquémosle la atención que merece.&lt;/p&gt;
&lt;h2 id="por-qué-importan-los-tipos-un-ejemplo-concreto"&gt;Por qué importan los tipos: un ejemplo concreto&lt;/h2&gt;
&lt;p&gt;Los tipos transmiten intención de forma explícita y verificable. Comparemos la misma función en JavaScript y en TypeScript:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// JavaScript
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;function&lt;/span&gt; &lt;span style="color:#e06c75"&gt;squareOf&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;n&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;n&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;*&lt;/span&gt; &lt;span style="color:#e06c75"&gt;n&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;squareOf&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;2&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;// 4
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;squareOf&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;z&amp;#39;&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;// NaN — falla en silencio
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// TypeScript
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;function&lt;/span&gt; &lt;span style="color:#e06c75"&gt;squareOf&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;n&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;n&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;*&lt;/span&gt; &lt;span style="color:#e06c75"&gt;n&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;squareOf&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;2&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;// 4
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;squareOf&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;z&amp;#39;&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;// Error TS2345: el argumento de tipo &amp;#39;string&amp;#39; no es
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#7f848e"&gt;// asignable al parámetro de tipo &amp;#39;number&amp;#39;.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;En JavaScript, &lt;code&gt;squareOf('z')&lt;/code&gt; devuelve &lt;code&gt;NaN&lt;/code&gt; sin protestar y el error se propaga aguas abajo. En TypeScript el compilador lo intercepta en el sitio exacto donde se cometió.&lt;/p&gt;
&lt;h2 id="any-la-puerta-de-escape-del-sistema-de-tipos"&gt;any: la puerta de escape del sistema de tipos&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;any&lt;/code&gt; indica que una variable puede contener cualquier tipo de dato. Desactiva por completo la verificación:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;avenger&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;any&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;123&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;avenger&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Dr. Strange&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;((&lt;span style="color:#e06c75"&gt;avenger&lt;/span&gt; &lt;span style="color:#c678dd"&gt;as&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;).&lt;span style="color:#e06c75"&gt;charAt&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;avenger&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;15.23425&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;((&amp;lt;&lt;span style="color:#e06c75"&gt;number&lt;/span&gt;&amp;gt;&lt;span style="color:#e06c75"&gt;avenger&lt;/span&gt;).&lt;span style="color:#e06c75"&gt;toFixed&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;2&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Cuando usas &lt;code&gt;any&lt;/code&gt;, el typechecker deja de ayudarte. Puedes reorientarlo mediante un &lt;em&gt;cast&lt;/em&gt; —indicar manualmente qué tipo debe asumir en un punto dado— con la sintaxis &lt;code&gt;(variable as Tipo)&lt;/code&gt; o &lt;code&gt;&amp;lt;Tipo&amp;gt;variable&lt;/code&gt;.&lt;/p&gt;




 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Evita &lt;code&gt;any&lt;/code&gt; salvo en migraciones puntuales o fronteras con código sin tipado. Cada &lt;code&gt;any&lt;/code&gt; es un agujero por el que se filtran errores que el compilador debería haber detenido.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="unknown-la-alternativa-segura-a-any"&gt;unknown: la alternativa segura a any&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;unknown&lt;/code&gt; es el primo responsable de &lt;code&gt;any&lt;/code&gt;. Acepta cualquier valor, pero &lt;strong&gt;TypeScript prohíbe operar sobre él&lt;/strong&gt; hasta que acotes su tipo mediante una comprobación. Esto añade una capa de seguridad: sí admite operaciones de comparación e identidad (&lt;code&gt;==&lt;/code&gt;, &lt;code&gt;===&lt;/code&gt;, &lt;code&gt;||&lt;/code&gt;, &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;, el operador ternario &lt;code&gt;?&lt;/code&gt;) y negación con &lt;code&gt;!&lt;/code&gt;, pero no el acceso a propiedades arbitrarias.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;dato&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;unknown&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;obtenerValor&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// dato.toFixed(2) // Error: &amp;#39;dato&amp;#39; es de tipo &amp;#39;unknown&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;if&lt;/span&gt; (&lt;span style="color:#c678dd"&gt;typeof&lt;/span&gt; &lt;span style="color:#e06c75"&gt;dato&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;===&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;number&amp;#39;&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;dato&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;toFixed&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;2&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;// OK: dentro del guard, dato es number
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Usa &lt;code&gt;unknown&lt;/code&gt; siempre que recibas datos externos (respuestas de API, entrada del usuario) en lugar de &lt;code&gt;any&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="boolean"&gt;boolean&lt;/h2&gt;
&lt;p&gt;Acepta las operaciones &lt;code&gt;==&lt;/code&gt;, &lt;code&gt;===&lt;/code&gt;, &lt;code&gt;||&lt;/code&gt;, &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;, el ternario &lt;code&gt;?&lt;/code&gt; y la negación &lt;code&gt;!&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;true&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// boolean
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;c&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;true&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// true (tipo literal)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;d&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;boolean&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;true&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// boolean
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;e&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;true&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;true&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;true&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;false&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// Error TS2322: &amp;#39;false&amp;#39; no es asignable a &amp;#39;true&amp;#39;.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;El tipo &lt;code&gt;true&lt;/code&gt; (literal) es más restrictivo que &lt;code&gt;boolean&lt;/code&gt;: además de exigir un booleano, exige que su valor sea exactamente &lt;code&gt;true&lt;/code&gt;. Los &lt;strong&gt;tipos literales&lt;/strong&gt; son una herramienta poderosa para modelar estados precisos.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="number-y-bigint"&gt;number y bigint&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;number&lt;/code&gt; cubre enteros, flotantes, &lt;code&gt;Infinity&lt;/code&gt;, &lt;code&gt;NaN&lt;/code&gt; y valores positivos y negativos:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1234&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// number
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;c&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;5678&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// 5678 (literal)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;e&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;100&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// number
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;26.218&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;26.218&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// 26.218 (literal)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;g&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;26.218&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;10&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// Error TS2322
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Un &lt;code&gt;number&lt;/code&gt; representa con precisión hasta 2^53. Para enteros mayores existe &lt;code&gt;bigint&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1234&lt;/span&gt;&lt;span style="color:#e06c75"&gt;n&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// bigint
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;b&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;5678&lt;/span&gt;&lt;span style="color:#e06c75"&gt;n&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// 5678n
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;e&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;88.5&lt;/span&gt;&lt;span style="color:#e06c75"&gt;n&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// Error TS1353: un literal bigint debe ser entero.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;h&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;bigint&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;100&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// Error TS2322: &amp;#39;100&amp;#39; no es asignable a &amp;#39;bigint&amp;#39;.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="string"&gt;string&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;hello&amp;#39;&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// string
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;c&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;!&amp;#39;&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// &amp;#39;!&amp;#39; (literal)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;e&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;zoom&amp;#39;&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// string
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;john&amp;#39;&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;john&amp;#39;&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// &amp;#39;john&amp;#39; (literal)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;g&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;john&amp;#39;&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;zoe&amp;#39;&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// Error TS2322
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="symbol"&gt;symbol&lt;/h2&gt;
&lt;p&gt;Un &lt;code&gt;symbol&lt;/code&gt; representa un identificador único. Se crea con &lt;code&gt;Symbol()&lt;/code&gt; y admite una descripción opcional útil para depurar:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Symbol&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;); &lt;span style="color:#7f848e"&gt;// symbol con descripción &amp;#34;id&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La garantía clave: &lt;strong&gt;dos símbolos nunca son iguales&lt;/strong&gt;, aunque compartan descripción. La descripción es solo una etiqueta sin efecto sobre la identidad.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;id1&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Symbol&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;id2&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Symbol&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;id1&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;===&lt;/span&gt; &lt;span style="color:#e06c75"&gt;id2&lt;/span&gt;); &lt;span style="color:#7f848e"&gt;// false
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;d&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;id1&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;+&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;x&amp;#39;&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// Error TS2469: el operador &amp;#39;+&amp;#39; no aplica a &amp;#39;symbol&amp;#39;.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="objetos"&gt;Objetos&lt;/h2&gt;
&lt;p&gt;Hay dos formas de tipar objetos. La primera usa la palabra clave &lt;code&gt;object&lt;/code&gt;, que solo garantiza que el valor no es &lt;code&gt;null&lt;/code&gt; pero &lt;strong&gt;no expone sus propiedades&lt;/strong&gt;, porque TypeScript no sabe qué objeto es:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;object&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;b&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;x&amp;#39;&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// a.b // Error: la propiedad &amp;#39;b&amp;#39; no existe en el tipo &amp;#39;object&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La segunda —y recomendada— describe la forma exacta del objeto:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;c&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;firstName&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;lastName&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;} &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;firstName&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;john&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;lastName&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;barrowman&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Las definiciones de objeto admiten campos opcionales (&lt;code&gt;?&lt;/code&gt;), índices dinámicos y propiedades de solo lectura:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;b&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// obligatorio, number
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;c?&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// opcional, string
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [&lt;span style="color:#e06c75"&gt;key&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;]&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#c678dd"&gt;boolean&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// cualquier clave numérica → boolean
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;user&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;readonly&lt;/span&gt; &lt;span style="color:#e06c75"&gt;firstName&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;} &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;firstName&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;abby&amp;#39;&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;user&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;firstName&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;abbey&amp;#39;&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// Error TS2540: propiedad de solo lectura.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



 
 





 


&lt;div class="notice tip"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z" /&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Tip&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Evita tipar con el objeto vacío &lt;code&gt;{}&lt;/code&gt;. Acepta cualquier valor distinto de &lt;code&gt;null&lt;/code&gt; o &lt;code&gt;undefined&lt;/code&gt; (incluso números o arreglos), lo que vacía de sentido la anotación.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="alias-de-tipo"&gt;Alias de tipo&lt;/h2&gt;
&lt;p&gt;Los alias asignan un nombre semántico a un tipo, mejorando la legibilidad sin alterar la verificación:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;type&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Age&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;type&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Person&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;age&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;Age&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;driver&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;Person&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;James May&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;age&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;55&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Como &lt;code&gt;Age&lt;/code&gt; es solo un alias de &lt;code&gt;number&lt;/code&gt;, sigue siendo compatible con cualquier &lt;code&gt;number&lt;/code&gt;. Ten presente que un alias &lt;strong&gt;solo puede declararse una vez&lt;/strong&gt; por ámbito; aplica las mismas reglas de &lt;em&gt;shadowing&lt;/em&gt; que &lt;code&gt;let&lt;/code&gt;, &lt;code&gt;const&lt;/code&gt; y &lt;code&gt;var&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="tipos-unión-e-intersección"&gt;Tipos unión e intersección&lt;/h2&gt;
&lt;p&gt;Recurriendo a la teoría de conjuntos: la &lt;strong&gt;unión&lt;/strong&gt; (&lt;code&gt;|&lt;/code&gt;) admite uno u otro tipo —o ambos—, mientras que la &lt;strong&gt;intersección&lt;/strong&gt; (&lt;code&gt;&amp;amp;&lt;/code&gt;) exige cumplir simultáneamente todas las formas combinadas.&lt;/p&gt;
&lt;pre class="mermaid"&gt;flowchart LR
 subgraph Union[&amp;#34;A | B&amp;#34;]
 U[Cualquier valor que sea A, B o ambos]
 end
 subgraph Inter[&amp;#34;A &amp;amp; B&amp;#34;]
 I[Solo valores que cumplen A y B a la vez]
 end
&lt;/pre&gt;

&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;type&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Cat&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;purrs&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;boolean&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;type&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Dog&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;barks&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;boolean&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;wags&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;boolean&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;type&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CatOrDogOrBoth&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Cat&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Dog&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// unión
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;type&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CatAndDog&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Cat&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Dog&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// intersección
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Un valor &lt;code&gt;Cat | Dog&lt;/code&gt; puede ser un gato, un perro o un objeto que cumpla ambas formas. Un valor &lt;code&gt;Cat &amp;amp; Dog&lt;/code&gt;, en cambio, está obligado a tener &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;purrs&lt;/code&gt;, &lt;code&gt;barks&lt;/code&gt; y &lt;code&gt;wags&lt;/code&gt; al mismo tiempo.&lt;/p&gt;
&lt;h2 id="arreglos"&gt;Arreglos&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; [&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;2&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;] &lt;span style="color:#7f848e"&gt;// number[]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;d&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; [&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;a&amp;#39;&lt;/span&gt;] &lt;span style="color:#7f848e"&gt;// (string | number)[]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;h&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;[] &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;h&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;push&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;// OK
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;h&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;push&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;red&amp;#39;&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;// Error TS2345
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Un arreglo declarado vacío sin anotación arranca como &lt;code&gt;any[]&lt;/code&gt; y va ampliando su tipo según lo que insertes —otra razón para anotar explícitamente las colecciones en las fronteras del sistema.&lt;/p&gt;
&lt;h2 id="tuplas"&gt;Tuplas&lt;/h2&gt;
&lt;p&gt;Las tuplas son un subconjunto de los arreglos con &lt;strong&gt;longitud fija&lt;/strong&gt; y tipos posicionales:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; [&lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;] &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; [&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// [nombre, apellido, año de nacimiento]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;b&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; [&lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;] &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; [&lt;span style="color:#98c379"&gt;&amp;#39;malcolm&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;gladwell&amp;#39;&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;1963&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;b&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; [&lt;span style="color:#98c379"&gt;&amp;#39;queen&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;elizabeth&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;ii&amp;#39;&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;1926&lt;/span&gt;] &lt;span style="color:#7f848e"&gt;// Error TS2322: posición/longitud inválida
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;También admiten posiciones opcionales:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// Tarifas de tren que a veces varían según la dirección
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;trainFares&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; [&lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;?&lt;/span&gt;][] &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [&lt;span style="color:#d19a66"&gt;3.75&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [&lt;span style="color:#d19a66"&gt;8.25&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;7.70&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [&lt;span style="color:#d19a66"&gt;10.50&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;El sistema de tipos de TypeScript va mucho más allá de etiquetar variables: distingue entre &lt;code&gt;any&lt;/code&gt; (inseguro) y &lt;code&gt;unknown&lt;/code&gt; (seguro), modela estados exactos con tipos literales, compone formas mediante uniones e intersecciones y garantiza estructuras rígidas con tuplas. Dominar este catálogo es el prerrequisito para los temas avanzados de la serie.&lt;/p&gt;
&lt;p&gt;En el siguiente artículo aplicaremos estos fundamentos a los &lt;strong&gt;objetos y tipos personalizados&lt;/strong&gt;, donde los alias de tipo se vuelven el centro del diseño.&lt;/p&gt;</content:encoded></item><item><title>Estilos CSS: Transiciones, transformaciones y rendimiento</title><link>https://blog.dacadev.com/programacion/estilos-css/transiciones-y-transformaciones/</link><pubDate>Sun, 14 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/programacion/estilos-css/transiciones-y-transformaciones/</guid><dc:creator>Dacadev</dc:creator><category>programación</category><description>Domina las transiciones y transformaciones en CSS: timing functions, las funciones transform (scale, rotate, translate, skew), perspectiva 3D y el pipeline de render.</description><media:content url="https://blog.dacadev.com/images/programming/html-and-css/css/07-transiciones-y-transformaciones-banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#transiciones"&gt;Transiciones&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#timing-functions"&gt;Timing functions&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#transformaciones"&gt;Transformaciones&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#rotación"&gt;Rotación&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#traslación"&gt;Traslación&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#escala"&gt;Escala&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#inclinación"&gt;Inclinación&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#punto-de-referencia-transform-origin"&gt;Punto de referencia: transform-origin&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#combinar-transformaciones"&gt;Combinar transformaciones&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#el-pipeline-de-renderizado"&gt;El pipeline de renderizado&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#transformaciones-en-3d"&gt;Transformaciones en 3D&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#conclusión"&gt;Conclusión&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;p&gt;Las transiciones y transformaciones son la puerta de entrada a las interfaces animadas. Una transición suaviza el cambio entre dos estados; una transformación altera la geometría visual de un elemento sin afectar el layout. Bien aplicadas, mejoran la percepción de calidad y guían la atención del usuario. Mal aplicadas, generan &lt;em&gt;jank&lt;/em&gt; y consumen batería. La diferencia está en entender qué propiedades son baratas de animar y por qué.&lt;/p&gt;
&lt;p&gt;Esta es la séptima entrega de la serie &lt;strong&gt;Estilos CSS&lt;/strong&gt;. Cubriremos la propiedad &lt;code&gt;transition&lt;/code&gt; y sus &lt;em&gt;timing functions&lt;/em&gt;, las funciones de &lt;code&gt;transform&lt;/code&gt; en 2D y 3D, y el pipeline de renderizado que explica por qué &lt;code&gt;transform&lt;/code&gt; y &lt;code&gt;opacity&lt;/code&gt; son las propiedades óptimas para animar.&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Aprenderás a construir transiciones fluidas con curvas de Bézier, a aplicar y combinar transformaciones, y a entender el pipeline layout → paint → composición para escribir animaciones eficientes.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="transiciones"&gt;Transiciones&lt;/h2&gt;
&lt;p&gt;Una transición interpola el cambio de una propiedad entre su valor inicial y final a lo largo del tiempo. Suele combinarse con pseudo-clases como &lt;code&gt;:hover&lt;/code&gt; o &lt;code&gt;:active&lt;/code&gt;. Se controla con cuatro propiedades:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;transition-property&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e06c75"&gt;background-color&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;,&lt;/span&gt; &lt;span style="color:#e06c75"&gt;transform&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;transition-duration&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e06c75"&gt;0&lt;/span&gt;.&lt;span style="color:#e5c07b"&gt;3s&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;,&lt;/span&gt; &lt;span style="color:#e06c75"&gt;0&lt;/span&gt;.&lt;span style="color:#e5c07b"&gt;6s&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;transition-timing-function&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ease&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;,&lt;/span&gt; &lt;span style="color:#e06c75"&gt;linear&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;transition-delay&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e06c75"&gt;0s&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;,&lt;/span&gt; &lt;span style="color:#e06c75"&gt;100ms&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;transition-property&lt;/code&gt;&lt;/strong&gt; — qué propiedades se animan (usa &lt;code&gt;all&lt;/code&gt; para todas).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;transition-duration&lt;/code&gt;&lt;/strong&gt; — cuánto dura la interpolación.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;transition-timing-function&lt;/code&gt;&lt;/strong&gt; — cómo se distribuye el movimiento en el tiempo.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;transition-delay&lt;/code&gt;&lt;/strong&gt; — cuánto espera antes de empezar (opcional).&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;boton&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;transition&lt;/span&gt;: &lt;span style="color:#c678dd"&gt;background-color&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0.3&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;s&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;ease&lt;/span&gt;, &lt;span style="color:#c678dd"&gt;transform&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0.3&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;s&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;ease&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;boton&lt;/span&gt;:&lt;span style="color:#61afef"&gt;hover&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;background-color&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;#16828d&lt;/span&gt;; &lt;span style="color:#c678dd"&gt;transform&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;translateY&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;-3&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;px&lt;/span&gt;); }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border:1px solid #d0d0d0;border-radius:.5rem;padding:1.5rem;background:#fff;margin:1rem 0;font-family:Helvetica,Arial,sans-serif;"&gt;
 &lt;style&gt;
 .cstrans { padding:.8em 1.6em; border:0; color:#fff; border-radius:.5em; cursor:pointer; background:#2a9da9; transition:background-color .3s ease, transform .3s ease, box-shadow .3s ease; box-shadow:0 .15em .4em rgba(0,0,0,.2); }
 .cstrans:hover { background:#16828d; transform:translateY(-4px); box-shadow:0 .4em .8em rgba(0,0,0,.3); }
 &lt;/style&gt;
 &lt;button class="cstrans" type="button"&gt;Pasa el cursor sobre mí&lt;/button&gt;
&lt;/div&gt;
&lt;h3 id="timing-functions"&gt;Timing functions&lt;/h3&gt;
&lt;p&gt;La &lt;em&gt;timing function&lt;/em&gt; define cómo se reparte el movimiento en el tiempo. Existen valores predefinidos —&lt;code&gt;linear&lt;/code&gt;, &lt;code&gt;ease&lt;/code&gt;, &lt;code&gt;ease-in&lt;/code&gt;, &lt;code&gt;ease-out&lt;/code&gt;, &lt;code&gt;ease-in-out&lt;/code&gt;— donde el eje X representa el tiempo y el eje Y el progreso del cambio.&lt;/p&gt;
&lt;p&gt;Todas son &lt;strong&gt;curvas de Bézier&lt;/strong&gt;, y puedes definir la tuya con la función &lt;code&gt;cubic-bezier()&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;box&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;transition&lt;/span&gt;: &lt;span style="color:#c678dd"&gt;transform&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0.6&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;s&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;cubic-bezier&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;0.45&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;0.05&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;0.55&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;0.95&lt;/span&gt;); }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;También puedes hacer el cambio en pasos discretos con &lt;code&gt;steps()&lt;/code&gt;, útil para animaciones tipo sprite o efectos de &amp;ldquo;tecleo&amp;rdquo;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;box&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;transition&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;all&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;s&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;steps&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;3&lt;/span&gt;); }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



 
 





 


&lt;div class="notice tip"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z" /&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Tip&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Existen editores visuales de curvas de Bézier que te permiten ajustar la animación y copiar el valor exacto. Experimentar con ellos es la forma más rápida de afinar la sensación de una transición.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="transformaciones"&gt;Transformaciones&lt;/h2&gt;
&lt;p&gt;La propiedad &lt;code&gt;transform&lt;/code&gt; altera la geometría visual de un elemento mediante cuatro operaciones:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;scale()&lt;/code&gt;&lt;/strong&gt; — escala el tamaño.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;rotate()&lt;/code&gt;&lt;/strong&gt; — rota el elemento.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;translate()&lt;/code&gt;&lt;/strong&gt; — lo desplaza.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;skew()&lt;/code&gt;&lt;/strong&gt; — lo inclina/estira.&lt;/li&gt;
&lt;/ul&gt;




 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Las transformaciones solo alteran la representación visual del elemento, &lt;strong&gt;no su comportamiento en el layout&lt;/strong&gt;. El hueco original que ocupaba se conserva, y los elementos vecinos no se reorganizan.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h3 id="rotación"&gt;Rotación&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;rotate()&lt;/code&gt; gira el elemento. Los valores positivos giran en sentido horario; los negativos, antihorario.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;giro&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;transform&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;rotate&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;15&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;deg&lt;/span&gt;); }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="traslación"&gt;Traslación&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;translate(x, y)&lt;/code&gt; mueve el elemento en ambos ejes sin afectar el flujo. Los valores positivos lo desplazan a la derecha y hacia abajo.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;mover&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;transform&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;translate&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;40&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;px&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;10&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;px&lt;/span&gt;); }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="escala"&gt;Escala&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;scale()&lt;/code&gt; redimensiona: valores entre 0 y 1 encogen, mayores que 1 agrandan.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;crecer&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;transform&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;scale&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;1.3&lt;/span&gt;); }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="inclinación"&gt;Inclinación&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;skew(x, y)&lt;/code&gt; deforma el elemento inclinándolo respecto a los ejes.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;inclinar&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;transform&lt;/span&gt;: &lt;span style="color:#61afef;font-weight:bold"&gt;skew&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;-12&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;deg&lt;/span&gt;); }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border:1px solid #d0d0d0;border-radius:.5rem;padding:1.5rem;background:#fff;margin:1rem 0;font-family:Helvetica,Arial,sans-serif;display:flex;gap:1.5rem;flex-wrap:wrap;align-items:center;justify-content:center;"&gt;
 &lt;span style="background:#2a9da9;color:#fff;padding:1em;border-radius:.4em;transform:rotate(15deg);display:inline-block;"&gt;rotate&lt;/span&gt;
 &lt;span style="background:#2a9da9;color:#fff;padding:1em;border-radius:.4em;transform:translate(0,-8px);display:inline-block;"&gt;translate&lt;/span&gt;
 &lt;span style="background:#2a9da9;color:#fff;padding:1em;border-radius:.4em;transform:scale(1.25);display:inline-block;"&gt;scale&lt;/span&gt;
 &lt;span style="background:#2a9da9;color:#fff;padding:1em;border-radius:.4em;transform:skew(-12deg);display:inline-block;"&gt;skew&lt;/span&gt;
&lt;/div&gt;
&lt;h3 id="punto-de-referencia-transform-origin"&gt;Punto de referencia: transform-origin&lt;/h3&gt;
&lt;p&gt;Toda transformación se aplica desde un punto de referencia, que por defecto es el centro del elemento. &lt;code&gt;transform-origin&lt;/code&gt; lo reubica:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;giro&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;transform-origin&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;left&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;center&lt;/span&gt;; } &lt;span style="color:#7f848e"&gt;/* equivale a 0% 50% */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="combinar-transformaciones"&gt;Combinar transformaciones&lt;/h3&gt;
&lt;p&gt;Puedes encadenar varias funciones separándolas por espacios. &lt;strong&gt;Se aplican de derecha a izquierda&lt;/strong&gt;, lo que afecta el resultado final:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;tarjeta&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;transform&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;rotate&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;15&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;deg&lt;/span&gt;) &lt;span style="color:#e5c07b"&gt;translate&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;20&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;px&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;); }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="el-pipeline-de-renderizado"&gt;El pipeline de renderizado&lt;/h2&gt;
&lt;p&gt;Para escribir animaciones eficientes hay que entender cómo el navegador dibuja una página. El proceso tiene tres etapas clave:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Layout&lt;/strong&gt; — el navegador calcula las dimensiones y posiciones de todos los elementos. Cualquier cambio de tamaño o posición dispara un recálculo completo (&lt;em&gt;reflow&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Paint&lt;/strong&gt; — pinta en memoria los píxeles de cada elemento (colores, bordes, sombras), posiblemente en capas separadas.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Composición&lt;/strong&gt; — combina las capas pintadas para mostrarlas en pantalla.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="mermaid"&gt;flowchart LR
 A[JS / CSS] --&amp;gt; B[Layout]
 B --&amp;gt; C[Paint]
 C --&amp;gt; D[Composición]
&lt;/pre&gt;

&lt;p&gt;La clave del rendimiento: algunas propiedades, como &lt;strong&gt;&lt;code&gt;transform&lt;/code&gt;&lt;/strong&gt; y &lt;strong&gt;&lt;code&gt;opacity&lt;/code&gt;&lt;/strong&gt;, solo afectan la etapa de &lt;strong&gt;composición&lt;/strong&gt;. No requieren recalcular el layout ni repintar, por lo que son las propiedades óptimas para animar de forma fluida a 60 fps.&lt;/p&gt;




 
 





 


&lt;div class="notice tip"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z" /&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Tip&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Prefiere animar &lt;code&gt;transform&lt;/code&gt; y &lt;code&gt;opacity&lt;/code&gt; en lugar de &lt;code&gt;width&lt;/code&gt;, &lt;code&gt;height&lt;/code&gt;, &lt;code&gt;top&lt;/code&gt; o &lt;code&gt;left&lt;/code&gt;. Estas últimas disparan layout y paint en cada frame, lo que produce animaciones entrecortadas.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="transformaciones-en-3d"&gt;Transformaciones en 3D&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;transform&lt;/code&gt; también opera en tres dimensiones. Puedes rotar sobre cualquier eje con &lt;code&gt;rotateX()&lt;/code&gt;, &lt;code&gt;rotateY()&lt;/code&gt; y &lt;code&gt;rotateZ()&lt;/code&gt;. El efecto depende de la &lt;strong&gt;perspectiva&lt;/strong&gt;: la distancia simulada entre el observador y el elemento. A menor perspectiva, más pronunciado el efecto 3D.&lt;/p&gt;
&lt;p&gt;Hay dos formas de aplicarla:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;/* 1. Función dentro de transform (afecta solo a ese elemento) */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;box&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;transform&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;perspective&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;200&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;px&lt;/span&gt;) &lt;span style="color:#e5c07b"&gt;rotateX&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;30&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;deg&lt;/span&gt;); }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;/* 2. Propiedad en el contenedor (perspectiva compartida) */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;row&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;perspective&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;200&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;px&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;box&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;transform&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;rotateX&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;30&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;deg&lt;/span&gt;); }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border:1px solid #d0d0d0;border-radius:.5rem;padding:1.5rem;background:#fff;margin:1rem 0;font-family:Helvetica,Arial,sans-serif;"&gt;
 &lt;div style="display:flex;justify-content:center;gap:2rem;perspective:300px;"&gt;
 &lt;div style="background:#2a9da9;color:#fff;padding:1.5em 1em;border-radius:.4em;transform:rotateX(35deg);"&gt;rotateX(35deg)&lt;/div&gt;
 &lt;div style="background:#16828d;color:#fff;padding:1.5em 1em;border-radius:.4em;transform:rotateY(35deg);"&gt;rotateY(35deg)&lt;/div&gt;
 &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Una rotación de 180° voltea el elemento como un espejo. La propiedad &lt;code&gt;backface-visibility&lt;/code&gt; controla si la cara trasera es visible, lo que habilita efectos como las tarjetas que se voltean. Un recurso clásico para profundizar es &lt;a href="https://3dtransforms.desandro.com/card-flip"




 target="_blank"
 


&gt;Intro to CSS 3D transforms&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;Las transiciones suavizan los cambios de estado y las transformaciones manipulan la geometría sin tocar el layout. La regla de oro del rendimiento es animar &lt;code&gt;transform&lt;/code&gt; y &lt;code&gt;opacity&lt;/code&gt;, que solo afectan la etapa de composición. Con curvas de Bézier afinadas y un uso consciente del pipeline, tus animaciones serán fluidas y eficientes.&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;🚀 La entrega final de la serie aborda la &lt;strong&gt;modularización y los patrones de diseño&lt;/strong&gt; en CSS: cómo organizar tus estilos en componentes mantenibles con metodologías como BEM.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
</content:encoded></item><item><title>SQL: Agrupamiento y Funciones Agregadas con GROUP BY</title><link>https://blog.dacadev.com/programacion/sql/04-agrupamiento-funciones-agregadas/</link><pubDate>Sun, 14 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/programacion/sql/04-agrupamiento-funciones-agregadas/</guid><dc:creator>Dacadev</dc:creator><category>programación</category><description>Aprende a usar GROUP BY en SQL para resumir datos con funciones agregadas, HAVING, DISTINCT y agrupaciones por columnas o expresiones.</description><media:content url="https://blog.dacadev.com/images/programming/sql/grouping-aggregates/banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#conceptos-de-agrupamiento-en-sql"&gt;Conceptos de agrupamiento en SQL&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#ordenar-resultados-agregados-con-order-by"&gt;Ordenar resultados agregados con &lt;code&gt;ORDER BY&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#filtrar-grupos-con-having"&gt;Filtrar grupos con &lt;code&gt;HAVING&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#funciones-agregadas-comunes"&gt;Funciones agregadas comunes&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#grupos-implícitos-vs-grupos-explícitos"&gt;Grupos implícitos vs grupos explícitos&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#contar-valores-distintos-con-countdistinct-"&gt;Contar valores distintos con &lt;code&gt;COUNT(DISTINCT ...)&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#generar-grupos-según-la-granularidad-requerida"&gt;Generar grupos según la granularidad requerida&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#agrupamiento-por-una-columna"&gt;Agrupamiento por una columna&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#agrupamiento-por-múltiples-columnas"&gt;Agrupamiento por múltiples columnas&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#agrupamiento-mediante-expresiones"&gt;Agrupamiento mediante expresiones&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#buenas-prácticas-al-trabajar-con-group-by"&gt;Buenas prácticas al trabajar con &lt;code&gt;GROUP BY&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#conclusión"&gt;Conclusión&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;p&gt;Cuando una tabla empieza a acumular miles o millones de filas, consultar registros individuales deja de ser suficiente. En análisis, reportes y validaciones operativas necesitamos resumir datos: cuántas rentas hizo cada cliente, cuánto pagó en total, cuál fue el monto máximo o qué categorías concentran más actividad. Para eso usamos &lt;strong&gt;agrupamiento en SQL&lt;/strong&gt; con &lt;code&gt;GROUP BY&lt;/code&gt; y &lt;strong&gt;funciones agregadas&lt;/strong&gt; como &lt;code&gt;COUNT&lt;/code&gt;, &lt;code&gt;SUM&lt;/code&gt;, &lt;code&gt;AVG&lt;/code&gt;, &lt;code&gt;MIN&lt;/code&gt; y &lt;code&gt;MAX&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Este es el artículo 4 de la serie SQL. Venimos de trabajar con &lt;a href="https://blog.dacadev.com/programacion/sql/03-logica-condicional-case"



 


&gt;lógica condicional con CASE&lt;/a&gt;, y ahora vamos a convertir filas transaccionales en resultados agregados listos para análisis.&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;En este artículo aprenderás a usar &lt;code&gt;GROUP BY&lt;/code&gt;, ordenar grupos con &lt;code&gt;ORDER BY&lt;/code&gt;, filtrar agregaciones con &lt;code&gt;HAVING&lt;/code&gt;, contar valores distintos con &lt;code&gt;DISTINCT&lt;/code&gt; y crear agrupaciones por una columna, múltiples columnas o expresiones.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="conceptos-de-agrupamiento-en-sql"&gt;Conceptos de agrupamiento en SQL&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;GROUP BY&lt;/code&gt; toma filas que comparten el mismo valor en una o más expresiones y las compacta en un grupo lógico. Si seleccionamos únicamente &lt;code&gt;customer_id&lt;/code&gt; desde &lt;code&gt;rental&lt;/code&gt;, SQL puede devolver cada cliente una sola vez:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;GROUP&lt;/span&gt; &lt;span style="color:#c678dd"&gt;BY&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;3&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;4&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;5&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;6&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;594&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;595&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;596&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;597&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;598&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;599&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;599&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;00&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El resultado ya no representa rentas individuales, sino el conjunto de clientes que aparecen en la tabla. El siguiente paso natural es medir cuántas filas contiene cada grupo. Para eso usamos &lt;code&gt;COUNT(*)&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt;, &lt;span style="color:#c678dd"&gt;count&lt;/span&gt;(&lt;span style="color:#56b6c2"&gt;*&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;GROUP&lt;/span&gt; &lt;span style="color:#c678dd"&gt;BY&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+----------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;count&lt;/span&gt;(&lt;span style="color:#56b6c2"&gt;*&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+----------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;32&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;27&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;3&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;26&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;4&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;22&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;5&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;38&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;6&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;28&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;594&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;27&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;595&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;30&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;596&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;28&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;597&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;25&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;598&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;22&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;599&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;19&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+----------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;599&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;01&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;&lt;code&gt;COUNT(*)&lt;/code&gt; le indica a SQL que cuente todas las filas contenidas dentro de cada grupo definido por &lt;code&gt;GROUP BY&lt;/code&gt;. No cuenta clientes únicos; cuenta filas dentro del grupo actual.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="ordenar-resultados-agregados-con-order-by"&gt;Ordenar resultados agregados con &lt;code&gt;ORDER BY&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Una agregación suele ser más útil cuando puedes priorizarla. Por ejemplo, para identificar los clientes con más rentas, ordenamos por la segunda columna del &lt;code&gt;SELECT&lt;/code&gt;, que en este caso es &lt;code&gt;count(*)&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt;, &lt;span style="color:#c678dd"&gt;count&lt;/span&gt;(&lt;span style="color:#56b6c2"&gt;*&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;GROUP&lt;/span&gt; &lt;span style="color:#c678dd"&gt;BY&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ORDER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;BY&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2&lt;/span&gt; &lt;span style="color:#c678dd"&gt;DESC&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+----------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;count&lt;/span&gt;(&lt;span style="color:#56b6c2"&gt;*&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+----------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;148&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;46&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;526&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;45&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;236&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;42&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;144&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;42&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;75&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;41&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;248&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;15&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;110&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;14&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;281&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;14&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;61&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;14&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;318&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;12&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+----------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;599&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;01&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



 
 





 


&lt;div class="notice tip"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z" /&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Tip&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;&lt;code&gt;ORDER BY&lt;/code&gt; puede usar el nombre de una columna, un alias o la posición de la columna dentro del &lt;code&gt;SELECT&lt;/code&gt;. Aun así, en consultas mantenibles suele ser más claro usar alias explícitos.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="filtrar-grupos-con-having"&gt;Filtrar grupos con &lt;code&gt;HAVING&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;WHERE&lt;/code&gt; filtra filas antes de que ocurra el agrupamiento. &lt;code&gt;HAVING&lt;/code&gt;, en cambio, filtra grupos después de calcular las agregaciones. Esta diferencia es crítica: no puedes usar &lt;code&gt;WHERE count(*) &amp;gt;= 40&lt;/code&gt; porque &lt;code&gt;count(*)&lt;/code&gt; todavía no existe en esa fase lógica de la consulta.&lt;/p&gt;
&lt;p&gt;Consideremos clientes con al menos 40 rentas:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt;, &lt;span style="color:#c678dd"&gt;count&lt;/span&gt;(&lt;span style="color:#56b6c2"&gt;*&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;GROUP&lt;/span&gt; &lt;span style="color:#c678dd"&gt;BY&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;HAVING&lt;/span&gt; &lt;span style="color:#c678dd"&gt;count&lt;/span&gt;(&lt;span style="color:#56b6c2"&gt;*&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;&amp;gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;40&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+----------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;count&lt;/span&gt;(&lt;span style="color:#56b6c2"&gt;*&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+----------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;75&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;41&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;144&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;42&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;148&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;46&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;197&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;40&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;236&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;42&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;469&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;40&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;526&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;45&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+----------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;7&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;01&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Analicemos el flujo conceptual: &lt;code&gt;FROM&lt;/code&gt; obtiene las filas, &lt;code&gt;WHERE&lt;/code&gt; descarta filas individuales, &lt;code&gt;GROUP BY&lt;/code&gt; crea grupos, las funciones agregadas calculan métricas y &lt;code&gt;HAVING&lt;/code&gt; descarta grupos completos. Por último, &lt;code&gt;ORDER BY&lt;/code&gt; organiza el resultado final.&lt;/p&gt;
&lt;h2 id="funciones-agregadas-comunes"&gt;Funciones agregadas comunes&lt;/h2&gt;
&lt;p&gt;Las bases de datos implementan distintas funciones agregadas, pero estas aparecen prácticamente en cualquier motor SQL:&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Función&lt;/th&gt;
 &lt;th&gt;Qué devuelve&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;MAX()&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;El valor máximo dentro de un conjunto&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;MIN()&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;El valor mínimo dentro de un conjunto&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;AVG()&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;El promedio de los valores del conjunto&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;SUM()&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;La suma total de los valores del conjunto&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;COUNT()&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;La cantidad de valores o filas del conjunto&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Sin &lt;code&gt;GROUP BY&lt;/code&gt;, estas funciones operan sobre toda la tabla o sobre el conjunto filtrado por &lt;code&gt;WHERE&lt;/code&gt;. Observemos un resumen global de pagos:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;MAX&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;amount&lt;/span&gt;) &lt;span style="color:#e06c75"&gt;max_amt&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;MIN&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;amount&lt;/span&gt;) &lt;span style="color:#e06c75"&gt;min_amt&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;AVG&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;amount&lt;/span&gt;) &lt;span style="color:#e06c75"&gt;avg_amt&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SUM&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;amount&lt;/span&gt;) &lt;span style="color:#e06c75"&gt;tot_amt&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;COUNT&lt;/span&gt;(&lt;span style="color:#56b6c2"&gt;*&lt;/span&gt;) &lt;span style="color:#e06c75"&gt;num_payments&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;payment&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------+---------+----------+----------+--------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;max_amt&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;min_amt&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;avg_amt&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;tot_amt&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;num_payments&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------+---------+----------+----------+--------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;11&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;99&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;00&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;4&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;200667&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;67416&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;51&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;16049&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------+---------+----------+----------+--------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#c678dd"&gt;row&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;09&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Aquí SQL devuelve una sola fila porque existe un grupo implícito: todo el resultado de &lt;code&gt;payment&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="grupos-implícitos-vs-grupos-explícitos"&gt;Grupos implícitos vs grupos explícitos&lt;/h2&gt;
&lt;p&gt;Cuando usamos una función agregada sin &lt;code&gt;GROUP BY&lt;/code&gt;, SQL resume todo el conjunto como un único grupo. Eso es útil para métricas globales, pero no sirve si necesitamos una métrica por cliente, actor, categoría o periodo.&lt;/p&gt;
&lt;p&gt;Para obtener métricas por cliente, definimos el grupo explícitamente:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;MAX&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;amount&lt;/span&gt;) &lt;span style="color:#e06c75"&gt;max_amt&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;MIN&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;amount&lt;/span&gt;) &lt;span style="color:#e06c75"&gt;min_amt&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;AVG&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;amount&lt;/span&gt;) &lt;span style="color:#e06c75"&gt;avg_amt&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SUM&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;amount&lt;/span&gt;) &lt;span style="color:#e06c75"&gt;tot_amt&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;COUNT&lt;/span&gt;(&lt;span style="color:#56b6c2"&gt;*&lt;/span&gt;) &lt;span style="color:#e06c75"&gt;num_payments&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;payment&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;GROUP&lt;/span&gt; &lt;span style="color:#c678dd"&gt;BY&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+---------+---------+----------+---------+--------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;max_amt&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;min_amt&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;avg_amt&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;tot_amt&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;num_payments&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+---------+---------+----------+---------+--------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;9&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;99&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;99&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;708750&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;118&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;68&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;32&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;10&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;99&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;99&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;4&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;767778&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;128&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;73&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;27&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;3&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;10&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;99&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;99&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;5&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;220769&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;135&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;74&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;26&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;4&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;8&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;99&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;99&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;717273&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;81&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;78&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;22&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;5&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;9&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;99&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;99&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;805789&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;144&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;62&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;38&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;6&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;7&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;99&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;99&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;347143&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;93&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;72&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;28&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;594&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;8&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;99&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;99&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;4&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;841852&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;130&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;73&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;27&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;595&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;10&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;99&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;99&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;923333&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;117&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;70&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;30&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;596&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;6&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;99&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;99&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;454286&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;96&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;72&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;28&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;597&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;8&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;99&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;99&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;990000&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;99&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;75&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;25&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;598&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;7&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;99&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;99&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;808182&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;83&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;78&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;22&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;599&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;9&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;99&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;99&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;4&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;411053&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;83&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;81&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;19&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+---------+---------+----------+---------+--------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;599&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;04&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La regla práctica es directa: cualquier columna no agregada en el &lt;code&gt;SELECT&lt;/code&gt; debe representar la granularidad del resultado y, por lo tanto, debe estar en el &lt;code&gt;GROUP BY&lt;/code&gt;.&lt;/p&gt;




 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Algunos motores permiten seleccionar columnas que no están agrupadas ni agregadas, pero el resultado puede ser ambiguo o depender de configuraciones del motor. Para consultas portables y correctas, declara explícitamente la granularidad.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="contar-valores-distintos-con-countdistinct-"&gt;Contar valores distintos con &lt;code&gt;COUNT(DISTINCT ...)&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;COUNT(*)&lt;/code&gt; cuenta filas. &lt;code&gt;COUNT(columna)&lt;/code&gt; cuenta valores no nulos de esa columna. &lt;code&gt;COUNT(DISTINCT columna)&lt;/code&gt; cuenta valores únicos, ignorando duplicados.&lt;/p&gt;
&lt;p&gt;Esto permite diferenciar entre el número de pagos registrados y el número de clientes distintos que hicieron pagos:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;COUNT&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt;) &lt;span style="color:#e06c75"&gt;num_rows&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;COUNT&lt;/span&gt;(&lt;span style="color:#c678dd"&gt;DISTINCT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt;) &lt;span style="color:#e06c75"&gt;num_customers&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;payment&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;----------+---------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;num_rows&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;num_customers&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;----------+---------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;16049&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;599&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;----------+---------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#c678dd"&gt;row&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;01&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Observemos que &lt;code&gt;num_rows&lt;/code&gt; refleja eventos de pago, mientras &lt;code&gt;num_customers&lt;/code&gt; refleja entidades únicas. Esa distinción evita errores frecuentes en reportes, especialmente cuando mezclamos métricas transaccionales con métricas de negocio.&lt;/p&gt;
&lt;h2 id="generar-grupos-según-la-granularidad-requerida"&gt;Generar grupos según la granularidad requerida&lt;/h2&gt;
&lt;p&gt;La calidad de una consulta agregada depende de elegir la granularidad correcta. No es lo mismo agrupar por cliente, por cliente y mes, por actor y clasificación, o por una expresión derivada de una fecha.&lt;/p&gt;
&lt;h3 id="agrupamiento-por-una-columna"&gt;Agrupamiento por una columna&lt;/h3&gt;
&lt;p&gt;Agrupar por una sola columna es el caso base. En este ejemplo obtenemos cuántas películas tiene asociadas cada actor:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;actor_id&lt;/span&gt;, &lt;span style="color:#c678dd"&gt;count&lt;/span&gt;(&lt;span style="color:#56b6c2"&gt;*&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film_actor&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;GROUP&lt;/span&gt; &lt;span style="color:#c678dd"&gt;BY&lt;/span&gt; &lt;span style="color:#e06c75"&gt;actor_id&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;----------+----------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;actor_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;count&lt;/span&gt;(&lt;span style="color:#56b6c2"&gt;*&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;----------+----------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;19&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;25&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;3&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;22&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;4&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;22&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;197&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;33&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;198&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;40&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;199&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;15&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;200&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;20&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;----------+----------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;200&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;11&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;En este resultado cada fila representa un actor y el conteo de películas en las que participa. La consulta ya no describe relaciones individuales &lt;code&gt;actor-película&lt;/code&gt;, sino un resumen por actor.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h3 id="agrupamiento-por-múltiples-columnas"&gt;Agrupamiento por múltiples columnas&lt;/h3&gt;
&lt;p&gt;En algunos casos necesitamos generar grupos que combinen más de una columna. Por ejemplo, contar cuántas películas tiene cada actor por clasificación (&lt;code&gt;G&lt;/code&gt;, &lt;code&gt;PG&lt;/code&gt;, &lt;code&gt;PG-13&lt;/code&gt;, &lt;code&gt;R&lt;/code&gt;, &lt;code&gt;NC-17&lt;/code&gt;):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fa&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;actor_id&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;rating&lt;/span&gt;, &lt;span style="color:#c678dd"&gt;count&lt;/span&gt;(&lt;span style="color:#56b6c2"&gt;*&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film_actor&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fa&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;INNER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fa&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;GROUP&lt;/span&gt; &lt;span style="color:#c678dd"&gt;BY&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fa&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;actor_id&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;rating&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ORDER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;BY&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;,&lt;span style="color:#d19a66"&gt;2&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;----------+--------+----------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;actor_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rating&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;count&lt;/span&gt;(&lt;span style="color:#56b6c2"&gt;*&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;----------+--------+----------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;G&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;4&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;PG&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;6&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;PG&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;13&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;R&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;3&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;NC&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;17&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;5&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;G&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;7&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;PG&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;6&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;PG&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;13&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;R&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;NC&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;17&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;8&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;199&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;G&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;3&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;199&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;PG&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;4&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;199&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;PG&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;13&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;4&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;199&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;R&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;199&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;NC&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;17&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;200&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;G&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;5&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;200&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;PG&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;3&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;200&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;PG&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;13&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;200&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;R&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;6&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;200&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;NC&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;17&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;4&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;----------+--------+----------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;996&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;01&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Aquí la granularidad ya no es “actor”, sino “actor + clasificación”. Cada combinación única genera su propio grupo. Esta técnica es la base para reportes multidimensionales y pivotes posteriores en herramientas de BI.&lt;/p&gt;
&lt;h3 id="agrupamiento-mediante-expresiones"&gt;Agrupamiento mediante expresiones&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;GROUP BY&lt;/code&gt; no está limitado a columnas físicas. También puede agrupar por expresiones, funciones o transformaciones calculadas. Esto es especialmente útil con fechas.&lt;/p&gt;
&lt;p&gt;El siguiente ejemplo agrupa rentas por año:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;extract&lt;/span&gt;(&lt;span style="color:#c678dd"&gt;YEAR&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental_date&lt;/span&gt;) &lt;span style="color:#c678dd"&gt;year&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;COUNT&lt;/span&gt;(&lt;span style="color:#56b6c2"&gt;*&lt;/span&gt;) &lt;span style="color:#e06c75"&gt;how_many&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;GROUP&lt;/span&gt; &lt;span style="color:#c678dd"&gt;BY&lt;/span&gt; &lt;span style="color:#c678dd"&gt;extract&lt;/span&gt;(&lt;span style="color:#c678dd"&gt;YEAR&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental_date&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------+----------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;year&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;how_many&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------+----------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2005&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;15862&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2006&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;182&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------+----------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;2&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;01&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;En lugar de agrupar por cada &lt;code&gt;rental_date&lt;/code&gt; exacto, reducimos la fecha al año con &lt;code&gt;EXTRACT(YEAR FROM rental_date)&lt;/code&gt;. El resultado responde una pregunta distinta: volumen anual, no eventos individuales.&lt;/p&gt;
&lt;h2 id="buenas-prácticas-al-trabajar-con-group-by"&gt;Buenas prácticas al trabajar con &lt;code&gt;GROUP BY&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Para mantener consultas claras y confiables, considera estas reglas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Define primero la &lt;strong&gt;granularidad&lt;/strong&gt;: una fila por cliente, por cliente y mes, por actor y rating, etc.&lt;/li&gt;
&lt;li&gt;Usa alias descriptivos para agregaciones: &lt;code&gt;num_payments&lt;/code&gt;, &lt;code&gt;total_amount&lt;/code&gt;, &lt;code&gt;avg_amount&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Aplica &lt;code&gt;WHERE&lt;/code&gt; para filtrar filas antes de agrupar y &lt;code&gt;HAVING&lt;/code&gt; para filtrar grupos.&lt;/li&gt;
&lt;li&gt;Evita depender de posiciones como &lt;code&gt;ORDER BY 2&lt;/code&gt; en consultas de producción si un alias mejora la legibilidad.&lt;/li&gt;
&lt;li&gt;Verifica si necesitas contar filas (&lt;code&gt;COUNT(*)&lt;/code&gt;), valores no nulos (&lt;code&gt;COUNT(columna)&lt;/code&gt;) o valores únicos (&lt;code&gt;COUNT(DISTINCT columna)&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;GROUP BY&lt;/code&gt; cambia la forma en que lees una tabla: pasas de inspeccionar filas individuales a construir resúmenes por la granularidad que necesita tu análisis. Combinado con funciones agregadas, &lt;code&gt;HAVING&lt;/code&gt;, &lt;code&gt;DISTINCT&lt;/code&gt; y expresiones, se convierte en una herramienta central para reportes, dashboards y validaciones de datos.&lt;/p&gt;
&lt;p&gt;En el siguiente artículo de la serie vamos a conectar datos distribuidos entre tablas con &lt;a href="https://blog.dacadev.com/programacion/sql/05-consultas-multiples-tablas-joins"



 


&gt;consultas a múltiples tablas usando JOINs&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title>TypeScript: Introducción y configuración del entorno</title><link>https://blog.dacadev.com/typescript/introduccion-a-typescript/</link><pubDate>Sun, 14 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/typescript/introduccion-a-typescript/</guid><dc:creator>Dacadev</dc:creator><category>programación</category><description>Aprende qué es TypeScript, cómo funciona su compilador, cómo instalarlo y configurar tsconfig.json para iniciar un proyecto profesional con tipado estático.</description><media:content url="https://blog.dacadev.com/images/typescript/introduction/banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#cómo-se-ejecuta-el-código-ast-bytecode-y-runtime"&gt;¿Cómo se ejecuta el código? AST, bytecode y runtime&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#el-sistema-de-tipos"&gt;El sistema de tipos&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#instalación-de-typescript"&gt;Instalación de TypeScript&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#tsconfigjson-el-corazón-de-la-configuración"&gt;tsconfig.json: el corazón de la configuración&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#el-archivo-de-entrada-indexts"&gt;El archivo de entrada: index.ts&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#hola-mundo-y-la-verificación-de-tipos-en-acción"&gt;Hola mundo y la verificación de tipos en acción&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#watch-mode-compilación-continua"&gt;Watch mode: compilación continua&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#conclusión"&gt;Conclusión&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;





 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Este artículo abre la serie sobre &lt;strong&gt;TypeScript&lt;/strong&gt;. Aquí analizaremos qué problema resuelve el tipado estático, cómo opera el compilador &lt;code&gt;tsc&lt;/code&gt; y cómo dejar listo un proyecto profesional con &lt;code&gt;tsconfig.json&lt;/code&gt;.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;JavaScript resuelve los tipos en tiempo de ejecución. Esto significa que un error tan trivial como pasar un &lt;code&gt;string&lt;/code&gt; donde se esperaba un &lt;code&gt;number&lt;/code&gt; solo se manifiesta cuando el código ya está corriendo, frecuentemente en producción y bajo la forma de un &lt;code&gt;NaN&lt;/code&gt; silencioso o una excepción difícil de rastrear. &lt;strong&gt;TypeScript&lt;/strong&gt; ataca este problema en la raíz: agrega un sistema de tipos estático sobre JavaScript que traslada la detección de errores desde el runtime hacia el tiempo de compilación.&lt;/p&gt;
&lt;h2 id="cómo-se-ejecuta-el-código-ast-bytecode-y-runtime"&gt;¿Cómo se ejecuta el código? AST, bytecode y runtime&lt;/h2&gt;
&lt;p&gt;Para entender qué aporta TypeScript conviene recordar el ciclo de vida de un programa en un motor de JavaScript:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;El programa se parsea hacia un &lt;strong&gt;AST&lt;/strong&gt; (Abstract Syntax Tree).&lt;/li&gt;
&lt;li&gt;El AST se compila a &lt;strong&gt;bytecode&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;El bytecode es evaluado por el &lt;strong&gt;runtime&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;TypeScript se inserta antes de este flujo. El compilador &lt;code&gt;tsc&lt;/code&gt; toma tu código &lt;code&gt;.ts&lt;/code&gt;, construye su propio AST, lo somete al &lt;strong&gt;typechecker&lt;/strong&gt; y, si todo es válido, emite JavaScript estándar que cualquier motor puede ejecutar.&lt;/p&gt;
&lt;pre class="mermaid"&gt;flowchart LR
 A[Código TypeScript] --&amp;gt; B[AST de TypeScript]
 B --&amp;gt; C{Typechecker}
 C -- válido --&amp;gt; D[JavaScript emitido]
 C -- error --&amp;gt; E[Error en compilación]
 D --&amp;gt; F[AST de JavaScript]
 F --&amp;gt; G[Bytecode]
 G --&amp;gt; H[Runtime]
&lt;/pre&gt;

&lt;p&gt;La conclusión clave: el typechecker es una capa de verificación que se ejecuta &lt;strong&gt;antes&lt;/strong&gt; de generar el JavaScript final. Los errores de tipo nunca llegan al runtime porque la compilación se detiene antes.&lt;/p&gt;
&lt;h2 id="el-sistema-de-tipos"&gt;El sistema de tipos&lt;/h2&gt;
&lt;p&gt;TypeScript admite tanto anotaciones de tipo explícitas como inferencia automática. Ambas estrategias coexisten en el mismo archivo:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// a es number
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;b&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;hello&amp;#39;&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// b es string
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;c&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;boolean&lt;/span&gt;[] &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; [&lt;span style="color:#e5c07b"&gt;true&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;false&lt;/span&gt;] &lt;span style="color:#7f848e"&gt;// c es un arreglo de booleanos
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// a es number (inferido)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;b&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;hello&amp;#39;&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// b es string (inferido)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;c&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; [&lt;span style="color:#e5c07b"&gt;true&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;false&lt;/span&gt;] &lt;span style="color:#7f848e"&gt;// c es boolean[] (inferido)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



 
 





 


&lt;div class="notice tip"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z" /&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Tip&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Apóyate en la inferencia siempre que el tipo sea evidente y reserva las anotaciones explícitas para las fronteras del sistema: firmas de funciones, APIs públicas y estructuras de datos compartidas. Esto reduce el ruido sin sacrificar seguridad.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;La diferencia esencial frente a JavaScript se resume así:&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Característica del sistema de tipos&lt;/th&gt;
 &lt;th&gt;JavaScript&lt;/th&gt;
 &lt;th&gt;TypeScript&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;¿Cómo se enlazan los tipos?&lt;/td&gt;
 &lt;td&gt;Dinámicamente&lt;/td&gt;
 &lt;td&gt;Estáticamente&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;¿Se convierten automáticamente?&lt;/td&gt;
 &lt;td&gt;Sí&lt;/td&gt;
 &lt;td&gt;No (en general)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;¿Cuándo se verifican?&lt;/td&gt;
 &lt;td&gt;En tiempo de ejecución&lt;/td&gt;
 &lt;td&gt;En tiempo de compilación&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;¿Cuándo afloran los errores?&lt;/td&gt;
 &lt;td&gt;En ejecución&lt;/td&gt;
 &lt;td&gt;En compilación&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="instalación-de-typescript"&gt;Instalación de TypeScript&lt;/h2&gt;
&lt;p&gt;TypeScript se distribuye como un paquete de Node, por lo que necesitas tener &lt;strong&gt;Node.js&lt;/strong&gt; instalado. Inicializa el proyecto y agrega las dependencias de desarrollo:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;npm init -y
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;npm install --save-dev typescript @types/node
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;@types/node&lt;/code&gt; aporta las definiciones de tipos del entorno de ejecución de Node, indispensables si vas a trabajar en el backend.&lt;/p&gt;
&lt;h2 id="tsconfigjson-el-corazón-de-la-configuración"&gt;tsconfig.json: el corazón de la configuración&lt;/h2&gt;
&lt;p&gt;El archivo &lt;code&gt;tsconfig.json&lt;/code&gt;, ubicado en la raíz del proyecto, define cómo el compilador interpreta y transforma tu código. Una configuración base sólida luce así:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;&amp;#34;compilerOptions&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;&amp;#34;lib&amp;#34;&lt;/span&gt;: [&lt;span style="color:#98c379"&gt;&amp;#34;es2015&amp;#34;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;&amp;#34;module&amp;#34;&lt;/span&gt;: &lt;span style="color:#98c379"&gt;&amp;#34;commonjs&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;&amp;#34;outDir&amp;#34;&lt;/span&gt;: &lt;span style="color:#98c379"&gt;&amp;#34;dist&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;&amp;#34;sourceMap&amp;#34;&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;&amp;#34;strict&amp;#34;&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;&amp;#34;target&amp;#34;&lt;/span&gt;: &lt;span style="color:#98c379"&gt;&amp;#34;es2015&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;&amp;#34;include&amp;#34;&lt;/span&gt;: [&lt;span style="color:#98c379"&gt;&amp;#34;src&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Cada opción cumple un rol concreto:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;include&lt;/code&gt;: indica las rutas donde &lt;code&gt;tsc&lt;/code&gt; debe buscar los archivos a compilar.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lib&lt;/code&gt;: declara qué librerías de tipos (APIs del entorno) asume disponibles el proyecto.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;module&lt;/code&gt;: define el sistema de módulos del código emitido (&lt;code&gt;commonjs&lt;/code&gt;, &lt;code&gt;esnext&lt;/code&gt;, etc.).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;outDir&lt;/code&gt;: ubicación de los archivos JavaScript compilados.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sourceMap&lt;/code&gt;: genera &lt;em&gt;source maps&lt;/em&gt; para depurar el TypeScript original desde el navegador o Node.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;strict&lt;/code&gt;: habilita el conjunto completo de comprobaciones estrictas. Es la opción que más valor aporta.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;target&lt;/code&gt;: versión de JavaScript a la que se transpila el código.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Puedes consultar el catálogo completo de opciones en la &lt;a href="https://www.typescriptlang.org/docs/handbook/compiler-options.html"




 target="_blank"
 


&gt;documentación oficial de tsc&lt;/a&gt;, o explorarlas desde la terminal:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;npx tsc --help
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;La opción &lt;code&gt;strict&lt;/code&gt; no es opcional en un proyecto serio. Activarla desde el primer commit evita una migración dolorosa más adelante, cuando el código ya arrastra cientos de tipos implícitos &lt;code&gt;any&lt;/code&gt;.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="el-archivo-de-entrada-indexts"&gt;El archivo de entrada: index.ts&lt;/h2&gt;
&lt;p&gt;El punto de entrada convencional es &lt;code&gt;src/index.ts&lt;/code&gt;. Comencemos con el clásico mensaje de prueba:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;hello world from TS!&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Compila el proyecto y ejecútalo:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;npx tsc
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;node ./dist/index.js
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;tsc&lt;/code&gt; lee la configuración de &lt;code&gt;tsconfig.json&lt;/code&gt;, transpila todo lo que esté bajo &lt;code&gt;src&lt;/code&gt; y deposita el resultado en &lt;code&gt;dist&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="hola-mundo-y-la-verificación-de-tipos-en-acción"&gt;Hola mundo y la verificación de tipos en acción&lt;/h2&gt;
&lt;p&gt;Observemos cómo el typechecker protege contra asignaciones inválidas:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;let&lt;/span&gt; &lt;span style="color:#e06c75"&gt;msg&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Hola mundo&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;msg&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;msg&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;David Casas&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;msg&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// msg = 123 // Error: number no es asignable a string
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Al compilar, TypeScript transpila a JavaScript plano eliminando las anotaciones:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;var&lt;/span&gt; &lt;span style="color:#e06c75"&gt;msg&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Hola mundo&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;msg&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;msg&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;David Casas&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;msg&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El tipo &lt;code&gt;string&lt;/code&gt; desaparece del código emitido porque su único propósito era validar en compilación. Esta propiedad —los tipos se borran tras la verificación— se conoce como &lt;em&gt;type erasure&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id="watch-mode-compilación-continua"&gt;Watch mode: compilación continua&lt;/h2&gt;
&lt;p&gt;Compilar manualmente tras cada cambio rompe el flujo de trabajo. El compilador incluye un &lt;strong&gt;modo observador&lt;/strong&gt; que recompila de forma incremental cada vez que detecta una modificación:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;npx tsc --watch
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;# o su forma corta&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;npx tsc -w
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Mantén este proceso abierto en una terminal mientras desarrollas: cada vez que guardes un archivo &lt;code&gt;.ts&lt;/code&gt;, verás de inmediato los errores de tipo o la salida actualizada en &lt;code&gt;dist&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;TypeScript no reemplaza a JavaScript; lo eleva añadiendo una capa de verificación estática que captura errores antes de ejecutar una sola línea. Con Node instalado, un &lt;code&gt;tsconfig.json&lt;/code&gt; en modo &lt;code&gt;strict&lt;/code&gt; y el compilador en &lt;em&gt;watch mode&lt;/em&gt;, ya tienes un entorno profesional listo para los siguientes temas de la serie.&lt;/p&gt;
&lt;p&gt;En el próximo artículo profundizaremos en los &lt;strong&gt;tipos básicos&lt;/strong&gt; del lenguaje: &lt;code&gt;any&lt;/code&gt;, &lt;code&gt;unknown&lt;/code&gt;, &lt;code&gt;number&lt;/code&gt;, &lt;code&gt;string&lt;/code&gt;, &lt;code&gt;symbol&lt;/code&gt;, objetos, uniones e intersecciones.&lt;/p&gt;</content:encoded></item><item><title>Estilos CSS: Fondos, gradientes y sombras</title><link>https://blog.dacadev.com/programacion/estilos-css/backgrounds-y-sombras/</link><pubDate>Fri, 12 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/programacion/estilos-css/backgrounds-y-sombras/</guid><dc:creator>Dacadev</dc:creator><category>programación</category><description>Aprende a trabajar con fondos en CSS: las propiedades background, gradientes lineales y radiales, modos de mezcla y sombras con box-shadow y text-shadow.</description><media:content url="https://blog.dacadev.com/images/programming/html-and-css/css/06-backgrounds-y-sombras-banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#la-familia-background"&gt;La familia background&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#gradientes-lineales"&gt;Gradientes lineales&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#gradientes-lineales-repetitivos"&gt;Gradientes lineales repetitivos&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#gradientes-radiales"&gt;Gradientes radiales&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#combinar-múltiples-fondos"&gt;Combinar múltiples fondos&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#texturas-con-blend-modes"&gt;Texturas con blend modes&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#sombras-box-shadow-y-text-shadow"&gt;Sombras: box-shadow y text-shadow&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#sombras-interiores-para-feedback"&gt;Sombras interiores para feedback&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#conclusión"&gt;Conclusión&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;p&gt;Los fondos y las sombras son las herramientas con las que CSS aporta profundidad, textura y jerarquía visual sin necesidad de imágenes externas. Un gradiente bien construido reemplaza un archivo PNG; una sombra sutil comunica que un botón es interactivo. Dominar estas propiedades te permite crear interfaces ricas con código puro, ligero y escalable.&lt;/p&gt;
&lt;p&gt;Esta es la sexta entrega de la serie &lt;strong&gt;Estilos CSS&lt;/strong&gt;. Recorreremos la familia de propiedades &lt;code&gt;background&lt;/code&gt;, los gradientes lineales y radiales, los modos de mezcla y las sombras de caja y de texto.&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Aprenderás a generar gradientes y patrones sin imágenes, a combinar varias capas de fondo y a usar &lt;code&gt;box-shadow&lt;/code&gt; y &lt;code&gt;text-shadow&lt;/code&gt; para dar realismo y feedback a tus componentes.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="la-familia-background"&gt;La familia background&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;background&lt;/code&gt; es una propiedad abreviada que agrupa ocho propiedades individuales:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;background-image&lt;/code&gt; — una imagen o un gradiente generado.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;background-position&lt;/code&gt; — la posición inicial del fondo.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;background-size&lt;/code&gt; — el tamaño de renderizado (&lt;code&gt;cover&lt;/code&gt;, &lt;code&gt;contain&lt;/code&gt;, valores explícitos).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;background-repeat&lt;/code&gt; — si la imagen se repite en mosaico.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;background-origin&lt;/code&gt; — respecto a qué caja se posiciona (border, padding o content).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;background-clip&lt;/code&gt; — hasta qué caja se extiende el fondo.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;background-attachment&lt;/code&gt; — si el fondo se desplaza con el contenido o queda fijo.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;background-color&lt;/code&gt; — un color sólido que se renderiza detrás de la imagen.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="gradientes-lineales"&gt;Gradientes lineales&lt;/h2&gt;
&lt;p&gt;Un gradiente es una transición de colores generada por una función de CSS, sin archivos. &lt;code&gt;linear-gradient()&lt;/code&gt; crea una transición a lo largo de una dirección.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;fade&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;background-image&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;linear-gradient&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;to&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;right&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;#fff&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;#2a9da9&lt;/span&gt;); }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border:1px solid #d0d0d0;border-radius:.5rem;padding:1rem;background:#fff;margin:1rem 0;"&gt;
 &lt;div style="height:80px;border-radius:.4em;background-image:linear-gradient(to right,#fff,#2a9da9);"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;La función acepta una dirección (&lt;code&gt;to right&lt;/code&gt;, &lt;code&gt;90deg&lt;/code&gt;, etc.) y una lista de colores. Puedes incluir más de dos colores y fijar su posición con porcentajes:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;fade&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;background-image&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;linear-gradient&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;90&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;deg&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;#c0392b&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;%&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;#fff&lt;/span&gt; &lt;span style="color:#d19a66"&gt;50&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;%&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;#2a9da9&lt;/span&gt; &lt;span style="color:#d19a66"&gt;100&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;%&lt;/span&gt;); }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border:1px solid #d0d0d0;border-radius:.5rem;padding:1rem;background:#fff;margin:1rem 0;"&gt;
 &lt;div style="height:80px;border-radius:.4em;background-image:linear-gradient(90deg,#c0392b 0%,#fff 50%,#2a9da9 100%);"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="gradientes-lineales-repetitivos"&gt;Gradientes lineales repetitivos&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;repeating-linear-gradient()&lt;/code&gt; crea patrones que se repiten, útil para texturas como rayas:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;rayas&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;background-image&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;repeating-linear-gradient&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;-45&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;deg&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#d19a66"&gt;#2a9da9&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;#2a9da9&lt;/span&gt; &lt;span style="color:#d19a66"&gt;10&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;px&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;#16828d&lt;/span&gt; &lt;span style="color:#d19a66"&gt;10&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;px&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;#16828d&lt;/span&gt; &lt;span style="color:#d19a66"&gt;20&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;px&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border:1px solid #d0d0d0;border-radius:.5rem;padding:1rem;background:#fff;margin:1rem 0;"&gt;
 &lt;div style="height:50px;border-radius:.4em;background-image:repeating-linear-gradient(-45deg,#2a9da9,#2a9da9 10px,#16828d 10px,#16828d 20px);"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="gradientes-radiales"&gt;Gradientes radiales&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;radial-gradient()&lt;/code&gt; genera una transición circular o elíptica que irradia desde un punto, en lugar de seguir una dirección lineal.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;brillo&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;background-image&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;radial-gradient&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;#fff&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;#2a9da9&lt;/span&gt;); }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border:1px solid #d0d0d0;border-radius:.5rem;padding:1rem;background:#fff;margin:1rem 0;"&gt;
 &lt;div style="height:120px;border-radius:.4em;background-image:radial-gradient(circle,#fff,#2a9da9);"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="combinar-múltiples-fondos"&gt;Combinar múltiples fondos&lt;/h2&gt;
&lt;p&gt;Puedes apilar varias capas de fondo separándolas con comas. La primera capa queda al frente. Esto permite, por ejemplo, superponer un gradiente sobre una imagen:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;heroe&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;background-image&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;linear-gradient&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;to&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;bottom&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;rgba&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;42&lt;/span&gt;,&lt;span style="color:#d19a66"&gt;157&lt;/span&gt;,&lt;span style="color:#d19a66"&gt;169&lt;/span&gt;,&lt;span style="color:#d19a66"&gt;0.6&lt;/span&gt;), &lt;span style="color:#e5c07b"&gt;rgba&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;22&lt;/span&gt;,&lt;span style="color:#d19a66"&gt;130&lt;/span&gt;,&lt;span style="color:#d19a66"&gt;141&lt;/span&gt;,&lt;span style="color:#d19a66"&gt;0.9&lt;/span&gt;)),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;url&lt;/span&gt;(&lt;span style="color:#98c379"&gt;foto.jpg&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;background-size&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;cover&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border:1px solid #d0d0d0;border-radius:.5rem;padding:1rem;background:#fff;margin:1rem 0;"&gt;
 &lt;div style="height:120px;border-radius:.4em;display:flex;align-items:center;justify-content:center;color:#fff;font-family:Helvetica,Arial,sans-serif;font-weight:bold;background-image:linear-gradient(135deg,rgba(42,157,169,.85),rgba(22,130,141,.95)),repeating-linear-gradient(45deg,#888,#888 8px,#777 8px,#777 16px);"&gt;Gradiente sobre una textura de fondo&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="texturas-con-blend-modes"&gt;Texturas con blend modes&lt;/h3&gt;
&lt;p&gt;La propiedad &lt;code&gt;background-blend-mode&lt;/code&gt; mezcla las capas de fondo entre sí (con modos como &lt;code&gt;multiply&lt;/code&gt;, &lt;code&gt;soft-light&lt;/code&gt;, &lt;code&gt;overlay&lt;/code&gt;), añadiendo textura a una imagen sin editarla en un programa externo:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;textura&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;background-image&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;url&lt;/span&gt;(&lt;span style="color:#98c379"&gt;rayones.png&lt;/span&gt;), &lt;span style="color:#e5c07b"&gt;url&lt;/span&gt;(&lt;span style="color:#98c379"&gt;foto.jpg&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;background-blend-mode&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;soft-light&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="sombras-box-shadow-y-text-shadow"&gt;Sombras: box-shadow y text-shadow&lt;/h2&gt;
&lt;p&gt;CSS permite añadir sombras tanto a las cajas (&lt;code&gt;box-shadow&lt;/code&gt;) como al texto (&lt;code&gt;text-shadow&lt;/code&gt;). Ambas reciben los mismos parámetros básicos:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Desplazamiento horizontal y vertical (&lt;code&gt;offset-x&lt;/code&gt;, &lt;code&gt;offset-y&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;El radio de difuminado (&lt;code&gt;blur&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;(opcional) El radio de expansión (&lt;code&gt;spread&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;El color de la sombra.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;tarjeta&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;box-shadow&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;0&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0.2&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;em&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0.5&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;em&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;rgba&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;0.25&lt;/span&gt;); }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;titulo&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;text-shadow&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;2&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;px&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;px&lt;/span&gt; &lt;span style="color:#d19a66"&gt;4&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;px&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;rgba&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;0.4&lt;/span&gt;); }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border:1px solid #d0d0d0;border-radius:.5rem;padding:1.5rem;background:#f4f6f7;margin:1rem 0;font-family:Helvetica,Arial,sans-serif;display:flex;gap:1.5rem;flex-wrap:wrap;align-items:center;"&gt;
 &lt;div style="background:#fff;color:#111;padding:1.2em 1.5em;border-radius:.5em;box-shadow:0 .2em .5em rgba(0,0,0,.25);"&gt;Tarjeta con &lt;code&gt;box-shadow&lt;/code&gt;&lt;/div&gt;
 &lt;span style="font-size:1.6rem;font-weight:bold;color:#2a9da9;text-shadow:2px 2px 4px rgba(0,0,0,.4);"&gt;Texto con text-shadow&lt;/span&gt;
&lt;/div&gt;
&lt;h3 id="sombras-interiores-para-feedback"&gt;Sombras interiores para feedback&lt;/h3&gt;
&lt;p&gt;La palabra clave &lt;code&gt;inset&lt;/code&gt; convierte la sombra en interior, perfecta para simular que un botón está presionado. Combinada con pseudo-clases como &lt;code&gt;:active&lt;/code&gt;, crea componentes con feedback táctil:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;boton&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;background-image&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;linear-gradient&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;to&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;bottom&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;#2a9da9&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;#16828d&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;box-shadow&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;0.1&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;em&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0.1&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;em&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0.5&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;em&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;rgba&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;,&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;,&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;,&lt;span style="color:#d19a66"&gt;0.4&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;color&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;#fff&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;boton&lt;/span&gt;:&lt;span style="color:#61afef"&gt;active&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;box-shadow&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;inset&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0.5&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;em&lt;/span&gt; &lt;span style="color:#d19a66"&gt;#0d4f56&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;inset&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0.5&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;em&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;em&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;rgba&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;,&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;,&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;,&lt;span style="color:#d19a66"&gt;0.4&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border:1px solid #d0d0d0;border-radius:.5rem;padding:1.5rem;background:#fff;margin:1rem 0;font-family:Helvetica,Arial,sans-serif;"&gt;
 &lt;style&gt;
 .csbtn { padding:1em 1.5em; border:0; font-size:.9rem; color:#fff; border-radius:.5em; cursor:pointer; background-image:linear-gradient(to bottom,#2a9da9,#16828d); box-shadow:.1em .1em .5em rgba(0,0,0,.4); }
 .csbtn:active { box-shadow:inset 0 0 .5em #0d4f56, inset 0 .5em 1em rgba(0,0,0,.4); }
 &lt;/style&gt;
 &lt;button class="csbtn" type="button"&gt;Mantén presionado este botón&lt;/button&gt;
 &lt;p style="margin:.75rem 0 0;color:#555;"&gt;Al pulsarlo, la sombra interior simula el hundido físico.&lt;/p&gt;
&lt;/div&gt;




 
 





 


&lt;div class="notice tip"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z" /&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Tip&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Las sombras se renderizan en la capa de composición y son baratas de animar. Una transición sutil de &lt;code&gt;box-shadow&lt;/code&gt; en &lt;code&gt;:hover&lt;/code&gt; comunica interactividad con un costo de rendimiento mínimo.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;Los gradientes y las sombras te permiten construir interfaces con profundidad y textura usando solo CSS, evitando peticiones de red y archivos de imagen. Apilar capas de fondo, mezclarlas con blend modes y aplicar sombras interiores son técnicas que elevan la calidad visual de cualquier componente.&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;🚀 La próxima entrega cubre &lt;strong&gt;transiciones y transformaciones&lt;/strong&gt;: cómo animar cambios de estado de forma fluida y manipular la geometría de los elementos con &lt;code&gt;transform&lt;/code&gt;.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
</content:encoded></item><item><title>RxJs: Peticiones HTTP/AJAX con rxjs/ajax y catchError</title><link>https://blog.dacadev.com/typescript/rxjs/peticiones-ajax-rxjs/</link><pubDate>Thu, 11 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/typescript/rxjs/peticiones-ajax-rxjs/</guid><dc:creator>Dacadev</dc:creator><category>programación</category><description>Aprende peticiones ajax rxjs con rxjs/ajax, getJSON, métodos HTTP y catchError rxjs para manejar errores en streams.</description><media:content url="https://blog.dacadev.com/images/typescript/rxjs/ajax/banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#fetch-frente-a-rxjsajax"&gt;fetch frente a rxjs/ajax&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#rxjs-ajax-para-peticiones-http"&gt;rxjs ajax para peticiones HTTP&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#catcherror-rxjs-recuperar-el-stream-ante-fallos"&gt;catchError rxjs: recuperar el stream ante fallos&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#ajaxgetjson-para-consumir-respuestas-json"&gt;ajax.getJSON para consumir respuestas JSON&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#métodos-post-put-y-delete-con-rxjsajax"&gt;Métodos post, put y delete con rxjs/ajax&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#configuración-avanzada-con-objeto"&gt;Configuración avanzada con objeto&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#composición-con-cancelación"&gt;Composición con cancelación&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#conclusión"&gt;Conclusión&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;p&gt;En aplicaciones frontend, las &lt;strong&gt;peticiones ajax rxjs&lt;/strong&gt; resultan útiles cuando el tráfico HTTP no es un evento aislado, sino parte de un flujo: búsquedas con cancelación, reintentos, composición con eventos de UI o coordinación entre varias fuentes asíncronas. &lt;code&gt;fetch&lt;/code&gt; cubre bien el caso imperativo basado en promesas, pero &lt;code&gt;rxjs/ajax&lt;/code&gt; integra las peticiones HTTP directamente con observables, operadores y suscripciones.&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Este artículo forma parte de la &lt;strong&gt;serie RxJs&lt;/strong&gt;. Venimos de analizar los &lt;a href="https://blog.dacadev.com/typescript/operadores-combinacion-observables/"



 


&gt;operadores de combinación&lt;/a&gt; y cerraremos la serie abordando &lt;code&gt;rxjs/ajax&lt;/code&gt;, &lt;code&gt;ajax.getJSON&lt;/code&gt;, métodos HTTP y &lt;code&gt;catchError rxjs&lt;/code&gt; para manejar fallos sin romper el flujo.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="fetch-frente-a-rxjsajax"&gt;fetch frente a rxjs/ajax&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;fetch&lt;/code&gt; es el estándar moderno del navegador para ejecutar peticiones HTTP. Su API está basada en &lt;code&gt;Promise&lt;/code&gt;, por lo que encaja bien cuando necesitas una única respuesta y un flujo de control lineal.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;url&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;https://api.github.com/users?per_page=5&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;manejaErrores&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;response&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;Response&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;if&lt;/span&gt; (&lt;span style="color:#56b6c2"&gt;!&lt;/span&gt;&lt;span style="color:#e06c75"&gt;response&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;ok&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;throw&lt;/span&gt; &lt;span style="color:#c678dd"&gt;new&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;Error&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;response&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;statusText&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;response&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;fetch&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;url&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e06c75"&gt;then&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;manejaErrores&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e06c75"&gt;then&lt;/span&gt;((&lt;span style="color:#e06c75"&gt;response&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;response&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;json&lt;/span&gt;())
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e06c75"&gt;then&lt;/span&gt;((&lt;span style="color:#e06c75"&gt;data&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;data&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;data&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#c678dd"&gt;catch&lt;/span&gt;((&lt;span style="color:#e06c75"&gt;error&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;warn&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;Error en usuarios&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;error&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La limitación aparece cuando la petición debe integrarse con otros streams. Una &lt;code&gt;Promise&lt;/code&gt; no tiene el concepto de suscripción, no emite múltiples valores y no se cancela por sí misma al dejar de interesarte el resultado. &lt;code&gt;fetch&lt;/code&gt; puede abortarse con &lt;code&gt;AbortController&lt;/code&gt;, pero esa cancelación queda como una responsabilidad externa que debes coordinar manualmente.&lt;/p&gt;
&lt;p&gt;Con RxJS, en cambio, la suscripción representa el ciclo de vida del trabajo asíncrono. En &lt;code&gt;rxjs/ajax&lt;/code&gt;, cancelar la suscripción aborta la petición subyacente basada en &lt;code&gt;XMLHttpRequest&lt;/code&gt;, lo cual encaja naturalmente con operadores como &lt;code&gt;switchMap&lt;/code&gt;, &lt;code&gt;takeUntil&lt;/code&gt; o &lt;code&gt;debounceTime&lt;/code&gt;.&lt;/p&gt;




 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Usa &lt;code&gt;fetch&lt;/code&gt; para flujos simples basados en una sola respuesta. Usa &lt;code&gt;rxjs/ajax&lt;/code&gt; cuando la petición forma parte de una arquitectura reactiva y necesitas composición, cancelación por suscripción o manejo declarativo de errores.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="rxjs-ajax-para-peticiones-http"&gt;rxjs ajax para peticiones HTTP&lt;/h2&gt;
&lt;p&gt;El módulo &lt;a href="https://rxjs.dev/api/ajax/ajax"




 target="_blank"
 


&gt;&lt;code&gt;rxjs/ajax&lt;/code&gt;&lt;/a&gt; expone la función &lt;code&gt;ajax&lt;/code&gt;, que devuelve un observable. Al suscribirte, se ejecuta la petición; al desuscribirte, se cancela si todavía está pendiente.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;ajax&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs/ajax&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;map&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;interface&lt;/span&gt; &lt;span style="color:#e06c75"&gt;GitHubUser&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;id&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;login&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;html_url&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;url&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;https://api.github.com/users?per_page=5&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;ajax&lt;/span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;GitHubUser&lt;/span&gt;[]&amp;gt;(&lt;span style="color:#e06c75"&gt;url&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;map&lt;/span&gt;((&lt;span style="color:#e06c75"&gt;ajaxResponse&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ajaxResponse&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;response&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e06c75"&gt;subscribe&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;next&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;users&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;usuarios&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;users&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;error&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;error&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;warn&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;Error en usuarios&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;error&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El observable emitido por &lt;code&gt;ajax&lt;/code&gt; no entrega únicamente el cuerpo. Entrega un &lt;code&gt;AjaxResponse&amp;lt;T&amp;gt;&lt;/code&gt; con metadatos como &lt;code&gt;status&lt;/code&gt;, &lt;code&gt;response&lt;/code&gt;, &lt;code&gt;request&lt;/code&gt; y &lt;code&gt;xhr&lt;/code&gt;. Esto es útil cuando la lógica depende del código HTTP, encabezados o detalles del transporte.&lt;/p&gt;
&lt;p&gt;Para obtener solo el cuerpo, el patrón habitual consiste en aplicar &lt;code&gt;map&lt;/code&gt; sobre &lt;code&gt;response&lt;/code&gt;. En versiones modernas de RxJS, importar operadores desde &lt;code&gt;rxjs&lt;/code&gt; mantiene el código conciso y compatible con el estilo recomendado.&lt;/p&gt;
&lt;h2 id="catcherror-rxjs-recuperar-el-stream-ante-fallos"&gt;catchError rxjs: recuperar el stream ante fallos&lt;/h2&gt;
&lt;p&gt;El operador &lt;a href="https://rxjs.dev/api/operators/catchError"




 target="_blank"
 


&gt;&lt;code&gt;catchError&lt;/code&gt;&lt;/a&gt; intercepta errores dentro de un observable y debe retornar un nuevo observable o un valor compatible con &lt;code&gt;ObservableInput&lt;/code&gt;. Esto permite reemplazar el flujo fallido por un valor seguro, reintentar con otra fuente o propagar un error enriquecido.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/ajax/marble-catcherror_hu_59aa604728b2d608.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 


&lt;p&gt;El diagrama muestra el punto clave: cuando ocurre un error, &lt;code&gt;catchError&lt;/code&gt; reemplaza el stream original por otro observable. Si no retornas un observable, la cadena queda en un estado inválido.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;of&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;ajax&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;AjaxError&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs/ajax&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;catchError&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;map&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;interface&lt;/span&gt; &lt;span style="color:#e06c75"&gt;GitHubUser&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;id&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;login&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;url&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;https://api.github.com/users?per_page=5&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;atrapaError&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;error&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;AjaxError&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;warn&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;Error:&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;error&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;message&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#c678dd"&gt;of&lt;/span&gt;([] &lt;span style="color:#c678dd"&gt;as&lt;/span&gt; &lt;span style="color:#e06c75"&gt;GitHubUser&lt;/span&gt;[]);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;ajax&lt;/span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;GitHubUser&lt;/span&gt;[]&amp;gt;(&lt;span style="color:#e06c75"&gt;url&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;map&lt;/span&gt;((&lt;span style="color:#e06c75"&gt;response&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;response&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;response&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;catchError&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;atrapaError&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e06c75"&gt;subscribe&lt;/span&gt;((&lt;span style="color:#e06c75"&gt;users&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;usuarios&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;users&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;En este ejemplo, el consumidor siempre recibe un arreglo. Si la petición falla, la UI puede renderizar un estado vacío sin romper la suscripción. Esta decisión es adecuada para listas tolerantes a fallo, pero no para operaciones donde ocultar el error afectaría consistencia o seguridad.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/ajax/console-catcherror_hu_4f892a08d295a73c.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 


&lt;p&gt;La salida de consola confirma que el error se captura dentro del pipeline y el stream continúa con el valor de reemplazo definido por &lt;code&gt;of&lt;/code&gt;.&lt;/p&gt;




 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;No uses &lt;code&gt;catchError&lt;/code&gt; para silenciar errores críticos de forma indiscriminada. Retorna valores de fallback solo cuando el dominio lo permite; en otros casos, transforma el error y propágalo con &lt;code&gt;throwError&lt;/code&gt;.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="ajaxgetjson-para-consumir-respuestas-json"&gt;ajax.getJSON para consumir respuestas JSON&lt;/h2&gt;
&lt;p&gt;Cuando solo necesitas el cuerpo JSON, &lt;code&gt;ajax.getJSON&lt;/code&gt; reduce el ruido del &lt;code&gt;AjaxResponse&lt;/code&gt;. Este método ejecuta una petición &lt;code&gt;GET&lt;/code&gt;, parsea la respuesta como JSON y permite enviar encabezados.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;ajax&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs/ajax&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;interface&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DelayResponse&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;headers&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;Record&lt;/span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;string&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;string&lt;/span&gt;&amp;gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;origin&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;url&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;url&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;https://httpbin.org/delay/1&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;response$&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ajax&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;getJSON&lt;/span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;DelayResponse&lt;/span&gt;&amp;gt;(&lt;span style="color:#e06c75"&gt;url&lt;/span&gt;, {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Content-Type&amp;#39;&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;application/json&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;mi-token&amp;#39;&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;1234&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;response$&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;subscribe&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;next&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;data&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;data&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;data&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;error&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;error&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;warn&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;Error en getJSON&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;error&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;getJSON&lt;/code&gt; es una buena opción para consultas simples donde no necesitas inspeccionar &lt;code&gt;status&lt;/code&gt;, &lt;code&gt;xhr&lt;/code&gt; o encabezados de respuesta. Si esos metadatos importan, usa &lt;code&gt;ajax&lt;/code&gt; directamente para conservar el contexto completo.&lt;/p&gt;
&lt;h2 id="métodos-post-put-y-delete-con-rxjsajax"&gt;Métodos post, put y delete con rxjs/ajax&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;rxjs/ajax&lt;/code&gt; también expone métodos especializados para verbos HTTP comunes: &lt;code&gt;ajax.get&lt;/code&gt;, &lt;code&gt;ajax.post&lt;/code&gt;, &lt;code&gt;ajax.put&lt;/code&gt;, &lt;code&gt;ajax.patch&lt;/code&gt; y &lt;code&gt;ajax.delete&lt;/code&gt;. Todos retornan observables y pueden participar en el mismo pipeline de operadores.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;ajax&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs/ajax&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;interface&lt;/span&gt; &lt;span style="color:#e06c75"&gt;UserPayload&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;id&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;interface&lt;/span&gt; &lt;span style="color:#e06c75"&gt;HttpBinResponse&lt;/span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;T&lt;/span&gt;&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;json&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;T&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;url&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;url&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;https://httpbin.org/anything/users&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;headers&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Content-Type&amp;#39;&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;application/json&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;x-client&amp;#39;&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs-demo&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;ajax&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;post&lt;/span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;HttpBinResponse&lt;/span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;UserPayload&lt;/span&gt;&amp;gt;&amp;gt;(&lt;span style="color:#e06c75"&gt;url&lt;/span&gt;, { &lt;span style="color:#e06c75"&gt;id&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;1&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Ada&amp;#39;&lt;/span&gt; }, &lt;span style="color:#e06c75"&gt;headers&lt;/span&gt;).&lt;span style="color:#e06c75"&gt;subscribe&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;next&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;response&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;POST&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;response&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;response&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;json&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;error&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;error&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;warn&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;Error en POST&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;error&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;ajax&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;put&lt;/span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;HttpBinResponse&lt;/span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;UserPayload&lt;/span&gt;&amp;gt;&amp;gt;(&lt;span style="color:#98c379"&gt;`&lt;/span&gt;&lt;span style="color:#98c379"&gt;${&lt;/span&gt;&lt;span style="color:#e06c75"&gt;url&lt;/span&gt;&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt;/1`&lt;/span&gt;, { &lt;span style="color:#e06c75"&gt;id&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;1&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Ada Lovelace&amp;#39;&lt;/span&gt; }, &lt;span style="color:#e06c75"&gt;headers&lt;/span&gt;).&lt;span style="color:#e06c75"&gt;subscribe&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;next&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;response&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;PUT&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;response&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;response&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;json&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;error&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;error&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;warn&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;Error en PUT&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;error&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;ajax&lt;/span&gt;.&lt;span style="color:#c678dd"&gt;delete&lt;/span&gt;(&lt;span style="color:#98c379"&gt;`&lt;/span&gt;&lt;span style="color:#98c379"&gt;${&lt;/span&gt;&lt;span style="color:#e06c75"&gt;url&lt;/span&gt;&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt;/1`&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;headers&lt;/span&gt;).&lt;span style="color:#e06c75"&gt;subscribe&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;next&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;response&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;DELETE&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;response&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;status&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;error&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;error&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;warn&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;Error en DELETE&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;error&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La forma especializada es legible cuando el método HTTP es fijo y la configuración es pequeña. Para casos con más parámetros, la forma de objeto suele ser más mantenible.&lt;/p&gt;
&lt;h2 id="configuración-avanzada-con-objeto"&gt;Configuración avanzada con objeto&lt;/h2&gt;
&lt;p&gt;La función &lt;code&gt;ajax&lt;/code&gt; acepta un objeto de configuración. Esta variante agrupa &lt;code&gt;url&lt;/code&gt;, &lt;code&gt;method&lt;/code&gt;, &lt;code&gt;headers&lt;/code&gt;, &lt;code&gt;body&lt;/code&gt;, &lt;code&gt;responseType&lt;/code&gt; y otros parámetros en una sola estructura, evitando firmas largas y facilitando la composición dinámica.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;ajax&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs/ajax&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;catchError&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;map&lt;/span&gt;, &lt;span style="color:#c678dd"&gt;of&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;interface&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CreateUserRequest&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;role&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;admin&amp;#39;&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;editor&amp;#39;&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;viewer&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;interface&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CreateUserResponse&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;json&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;CreateUserRequest&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;url&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;requestBody&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;CreateUserRequest&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Grace Hopper&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;role&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;admin&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;createUser$&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ajax&lt;/span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;CreateUserResponse&lt;/span&gt;&amp;gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;url&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;https://httpbin.org/anything/users&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;method&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;POST&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;headers&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Content-Type&amp;#39;&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;application/json&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;Authorization&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Bearer demo-token&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;body&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;requestBody&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;responseType&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;json&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}).&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;map&lt;/span&gt;((&lt;span style="color:#e06c75"&gt;response&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;response&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;response&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;json&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;catchError&lt;/span&gt;((&lt;span style="color:#e06c75"&gt;error&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;warn&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;No fue posible crear el usuario&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;error&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#c678dd"&gt;of&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;null&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;createUser$&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;subscribe&lt;/span&gt;((&lt;span style="color:#e06c75"&gt;user&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;usuario creado&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;user&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Esta forma es especialmente útil en servicios donde construyes peticiones desde parámetros de dominio. También facilita extraer una función reutilizable que retorne un observable tipado sin ejecutar la petición hasta que exista una suscripción.&lt;/p&gt;




 
 





 


&lt;div class="notice tip"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z" /&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Tip&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Mantén las funciones HTTP como fábricas de observables: reciben parámetros de dominio y retornan &lt;code&gt;Observable&amp;lt;T&amp;gt;&lt;/code&gt;. Evita suscribirte dentro del servicio si el consumidor necesita cancelar, componer o manejar errores en una capa superior.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="composición-con-cancelación"&gt;Composición con cancelación&lt;/h2&gt;
&lt;p&gt;Una de las ventajas prácticas de &lt;code&gt;rxjs/ajax&lt;/code&gt; aparece en búsquedas o autocompletados. &lt;code&gt;switchMap&lt;/code&gt; cancela la petición anterior cuando llega un nuevo término, evitando condiciones de carrera y respuestas obsoletas.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;fromEvent&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;ajax&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs/ajax&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;catchError&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;debounceTime&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;distinctUntilChanged&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;map&lt;/span&gt;, &lt;span style="color:#c678dd"&gt;of&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;switchMap&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;input&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;document&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;querySelector&lt;/span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;HTMLInputElement&lt;/span&gt;&amp;gt;(&lt;span style="color:#98c379"&gt;&amp;#39;#search&amp;#39;&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;!&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;results$&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fromEvent&lt;/span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;InputEvent&lt;/span&gt;&amp;gt;(&lt;span style="color:#e06c75"&gt;input&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;input&amp;#39;&lt;/span&gt;).&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;map&lt;/span&gt;((&lt;span style="color:#e06c75"&gt;event&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;event&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;target&lt;/span&gt; &lt;span style="color:#c678dd"&gt;as&lt;/span&gt; &lt;span style="color:#e06c75"&gt;HTMLInputElement&lt;/span&gt;).&lt;span style="color:#e06c75"&gt;value&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;trim&lt;/span&gt;()),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;debounceTime&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;300&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;distinctUntilChanged&lt;/span&gt;(),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;switchMap&lt;/span&gt;((&lt;span style="color:#e06c75"&gt;query&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;if&lt;/span&gt; (&lt;span style="color:#56b6c2"&gt;!&lt;/span&gt;&lt;span style="color:#e06c75"&gt;query&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#c678dd"&gt;of&lt;/span&gt;([]);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ajax&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;getJSON&lt;/span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;unknown&lt;/span&gt;[]&amp;gt;(&lt;span style="color:#98c379"&gt;`/api/search?q=&lt;/span&gt;&lt;span style="color:#98c379"&gt;${&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;encodeURIComponent&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;query&lt;/span&gt;)&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt;`&lt;/span&gt;).&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;catchError&lt;/span&gt;(() &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;of&lt;/span&gt;([])),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; );
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;results$&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;subscribe&lt;/span&gt;((&lt;span style="color:#e06c75"&gt;results&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;renderResults&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;results&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Con &lt;code&gt;fetch&lt;/code&gt;, este patrón requiere coordinar manualmente &lt;code&gt;AbortController&lt;/code&gt; para cada búsqueda pendiente. Con RxJS, la cancelación es una consecuencia directa de la desuscripción que &lt;code&gt;switchMap&lt;/code&gt; realiza sobre el observable interno anterior.&lt;/p&gt;
&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;rxjs/ajax&lt;/code&gt; convierte las peticiones HTTP en streams composables. Esta integración permite mapear respuestas, centralizar errores con &lt;code&gt;catchError&lt;/code&gt;, cancelar trabajo pendiente mediante desuscripción y coordinar tráfico HTTP con eventos de interfaz o temporizadores.&lt;/p&gt;
&lt;p&gt;Con este artículo cerramos la serie RxJs: partimos de la naturaleza de los observables, recorrimos funciones de creación, operadores básicos, transformación, combinación y finalmente peticiones AJAX. El objetivo común fue diseñar flujos asíncronos explícitos, cancelables y mantenibles usando las primitivas reactivas correctas.&lt;/p&gt;</content:encoded></item><item><title>SQL: Lógica Condicional con la Expresión CASE</title><link>https://blog.dacadev.com/programacion/sql/03-logica-condicional-case/</link><pubDate>Thu, 11 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/programacion/sql/03-logica-condicional-case/</guid><dc:creator>Dacadev</dc:creator><category>programación</category><description>Aprende a usar CASE en SQL para crear lógica condicional, clasificar datos, evitar división por cero y manejar NULL correctamente.</description><media:content url="https://blog.dacadev.com/images/programming/sql/conditional-logic/banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#la-expresión-case"&gt;La expresión CASE&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#searched-case"&gt;Searched CASE&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#simple-case"&gt;Simple CASE&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#comprobar-la-existencia"&gt;Comprobar la existencia&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#errores-de-división-por-cero"&gt;Errores de división por cero&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#actualizaciones-condicionales"&gt;Actualizaciones condicionales&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#manejo-de-valores-null"&gt;Manejo de valores NULL&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#cierre"&gt;Cierre&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;p&gt;Cuando una consulta necesita clasificar registros, calcular valores derivados o protegerse de casos límite, la &lt;strong&gt;lógica condicional en SQL&lt;/strong&gt; evita mover decisiones simples a la capa de aplicación. Después de trabajar con &lt;a href="https://blog.dacadev.com/programacion/sql/02-filtrado-datos-clausula-where"



 


&gt;filtrado de datos con WHERE&lt;/a&gt;, el siguiente paso natural es usar la &lt;strong&gt;expresión CASE&lt;/strong&gt; para transformar resultados directamente dentro del query.&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;En este artículo analizaremos cómo usar &lt;code&gt;CASE&lt;/code&gt; en SQL con condiciones múltiples, validaciones de existencia, protección contra división por cero, actualizaciones condicionales y manejo explícito de valores &lt;code&gt;NULL&lt;/code&gt;.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;La expresión &lt;code&gt;CASE&lt;/code&gt; cumple un rol similar a &lt;code&gt;if / else if / else&lt;/code&gt; o &lt;code&gt;switch / case&lt;/code&gt; en lenguajes de programación. Su valor está en que opera dentro del motor de base de datos: puedes derivar columnas, etiquetar estados y condicionar cálculos sin postprocesar cada fila en tu backend.&lt;/p&gt;
&lt;p&gt;Observemos un primer ejemplo directo. A partir de una columna &lt;code&gt;active&lt;/code&gt;, convertimos &lt;code&gt;1&lt;/code&gt; y &lt;code&gt;0&lt;/code&gt; en etiquetas más legibles:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;CASE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHEN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;active&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#c678dd"&gt;THEN&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;ACTIVE&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ELSE&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;INACTIVE&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;END&lt;/span&gt; &lt;span style="color:#e06c75"&gt;activity_type&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+--------------+---------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;activity_type&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+--------------+---------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;MARY&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SMITH&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ACTIVE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;PATRICIA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JOHNSON&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ACTIVE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;LINDA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;WILLIAMS&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ACTIVE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;BARBARA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JONES&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ACTIVE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ELIZABETH&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;BROWN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ACTIVE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JENNIFER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DAVIS&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ACTIVE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;KENT&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ARSENAULT&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ACTIVE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;TERRANCE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ROUSH&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;INACTIVE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;RENE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;MCALISTER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ACTIVE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;EDUARDO&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;HIATT&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ACTIVE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;TERRENCE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;GUNDERSON&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ACTIVE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ENRIQUE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FORSYTHE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ACTIVE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FREDDIE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DUGGAN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ACTIVE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;WADE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DELVALLE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ACTIVE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;AUSTIN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CINTRON&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ACTIVE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+--------------+---------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;599&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;00&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="la-expresión-case"&gt;La expresión CASE&lt;/h2&gt;
&lt;p&gt;La expresión &lt;code&gt;CASE&lt;/code&gt; evalúa una o varias condiciones y retorna un valor según la primera coincidencia encontrada. En SQL, &lt;code&gt;CASE&lt;/code&gt; no es solo una herramienta cosmética; también permite modelar reglas de negocio dentro de consultas, reportes y operaciones &lt;code&gt;UPDATE&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Existen dos variantes principales:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Searched CASE&lt;/strong&gt;: cada &lt;code&gt;WHEN&lt;/code&gt; contiene una condición completa.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Simple CASE&lt;/strong&gt;: se evalúa una expresión base contra valores específicos.&lt;/li&gt;
&lt;/ul&gt;




 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Si ninguna condición coincide y no defines &lt;code&gt;ELSE&lt;/code&gt;, el resultado de &lt;code&gt;CASE&lt;/code&gt; será &lt;code&gt;NULL&lt;/code&gt;. Conviene declarar &lt;code&gt;ELSE&lt;/code&gt; explícitamente cuando el consumidor del dato espera una categoría estable.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="searched-case"&gt;Searched CASE&lt;/h2&gt;
&lt;p&gt;El &lt;strong&gt;Searched CASE&lt;/strong&gt; es la forma más flexible porque cada rama puede evaluar una condición distinta. Su estructura general es:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;CASE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;WHEN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;C1&lt;/span&gt; &lt;span style="color:#c678dd"&gt;THEN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;E1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;WHEN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;C2&lt;/span&gt; &lt;span style="color:#c678dd"&gt;THEN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;E2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;WHEN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CN&lt;/span&gt; &lt;span style="color:#c678dd"&gt;THEN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;EN&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [&lt;span style="color:#c678dd"&gt;ELSE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ED&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;END&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;En este patrón, &lt;code&gt;C1&lt;/code&gt;, &lt;code&gt;C2&lt;/code&gt; y &lt;code&gt;CN&lt;/code&gt; representan condiciones booleanas. Cuando una condición se cumple, &lt;code&gt;CASE&lt;/code&gt; retorna su expresión asociada (&lt;code&gt;E1&lt;/code&gt;, &lt;code&gt;E2&lt;/code&gt;, &lt;code&gt;EN&lt;/code&gt;) y deja de evaluar las siguientes ramas.&lt;/p&gt;
&lt;p&gt;Analicemos una clasificación de categorías de películas:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;CASE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;WHEN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;category&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;name&lt;/span&gt; &lt;span style="color:#c678dd"&gt;IN&lt;/span&gt; (&lt;span style="color:#98c379"&gt;&amp;#39;Children&amp;#39;&lt;/span&gt;,&lt;span style="color:#98c379"&gt;&amp;#39;Family&amp;#39;&lt;/span&gt;,&lt;span style="color:#98c379"&gt;&amp;#39;Sports&amp;#39;&lt;/span&gt;,&lt;span style="color:#98c379"&gt;&amp;#39;Animation&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;THEN&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;All Ages&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;WHEN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;category&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Horror&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;THEN&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Adult&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;WHEN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;category&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;name&lt;/span&gt; &lt;span style="color:#c678dd"&gt;IN&lt;/span&gt; (&lt;span style="color:#98c379"&gt;&amp;#39;Music&amp;#39;&lt;/span&gt;,&lt;span style="color:#98c379"&gt;&amp;#39;Games&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;THEN&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Teens&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;ELSE&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Other&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;END&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Esta variante permite mezclar operadores como &lt;code&gt;IN&lt;/code&gt;, &lt;code&gt;=&lt;/code&gt;, comparaciones numéricas, subconsultas y funciones. También se puede usar para evitar cálculos innecesarios en ciertas filas.&lt;/p&gt;
&lt;p&gt;Consideremos el siguiente caso: si un cliente está inactivo, queremos retornar &lt;code&gt;0&lt;/code&gt;; si está activo, contamos sus rentas:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;, &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;CASE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHEN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;active&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0&lt;/span&gt; &lt;span style="color:#c678dd"&gt;THEN&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ELSE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; (&lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;count&lt;/span&gt;(&lt;span style="color:#56b6c2"&gt;*&lt;/span&gt;) &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental&lt;/span&gt; &lt;span style="color:#e06c75"&gt;r&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;r&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;END&lt;/span&gt; &lt;span style="color:#e06c75"&gt;num_rentals&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+--------------+-------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;num_rentals&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+--------------+-------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;MARY&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SMITH&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;32&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;PATRICIA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JOHNSON&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;27&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;LINDA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;WILLIAMS&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;26&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;BARBARA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JONES&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;22&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ELIZABETH&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;BROWN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;38&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JENNIFER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DAVIS&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;28&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;TERRANCE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ROUSH&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;RENE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;MCALISTER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;26&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;EDUARDO&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;HIATT&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;27&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;TERRENCE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;GUNDERSON&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;30&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ENRIQUE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FORSYTHE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;28&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FREDDIE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DUGGAN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;25&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;WADE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DELVALLE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;22&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;AUSTIN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CINTRON&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;19&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+--------------+-------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;599&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;01&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="simple-case"&gt;Simple CASE&lt;/h2&gt;
&lt;p&gt;El &lt;strong&gt;Simple CASE&lt;/strong&gt; es útil cuando todas las ramas comparan la misma expresión contra valores concretos. En lugar de repetir &lt;code&gt;category.name = ...&lt;/code&gt;, colocamos &lt;code&gt;category.name&lt;/code&gt; una sola vez después de &lt;code&gt;CASE&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;CASE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;category&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;WHEN&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Children&amp;#39;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;THEN&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;All Ages&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;WHEN&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Family&amp;#39;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;THEN&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;All Ages&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;WHEN&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Sports&amp;#39;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;THEN&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;All Ages&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;WHEN&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Animation&amp;#39;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;THEN&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;All Ages&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;WHEN&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Horror&amp;#39;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;THEN&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Adult&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;WHEN&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Music&amp;#39;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;THEN&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Teens&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;WHEN&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Games&amp;#39;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;THEN&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Teens&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;ELSE&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Other&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;END&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Esta forma es más compacta y legible cuando la decisión depende de una única columna o expresión. Su limitación es que no permite condiciones heterogéneas por rama; para eso conviene usar &lt;code&gt;Searched CASE&lt;/code&gt;.&lt;/p&gt;




 
 





 


&lt;div class="notice tip"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z" /&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Tip&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Usa &lt;code&gt;Simple CASE&lt;/code&gt; cuando estás mapeando valores discretos de una misma columna. Usa &lt;code&gt;Searched CASE&lt;/code&gt; cuando necesitas rangos, &lt;code&gt;IN&lt;/code&gt;, &lt;code&gt;EXISTS&lt;/code&gt;, comparaciones entre columnas o reglas más compuestas.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="comprobar-la-existencia"&gt;Comprobar la existencia&lt;/h2&gt;
&lt;p&gt;Uno de los usos más prácticos de &lt;code&gt;CASE&lt;/code&gt; es combinarlo con &lt;code&gt;EXISTS&lt;/code&gt;. Esta técnica permite crear columnas tipo bandera (&lt;code&gt;Y&lt;/code&gt; / &lt;code&gt;N&lt;/code&gt;, &lt;code&gt;true&lt;/code&gt; / &lt;code&gt;false&lt;/code&gt;, &lt;code&gt;1&lt;/code&gt; / &lt;code&gt;0&lt;/code&gt;) según la existencia de filas relacionadas.&lt;/p&gt;
&lt;p&gt;Observemos una consulta que marca si un actor participó en películas con ciertas clasificaciones:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;CASE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHEN&lt;/span&gt; &lt;span style="color:#c678dd"&gt;EXISTS&lt;/span&gt; (&lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film_actor&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fa&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;INNER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fa&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fa&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;actor_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;actor_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;AND&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;rating&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;G&amp;#39;&lt;/span&gt;) &lt;span style="color:#c678dd"&gt;THEN&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Y&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ELSE&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;N&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;END&lt;/span&gt; &lt;span style="color:#e06c75"&gt;g_actor&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;CASE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHEN&lt;/span&gt; &lt;span style="color:#c678dd"&gt;EXISTS&lt;/span&gt; (&lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film_actor&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fa&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;INNER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fa&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fa&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;actor_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;actor_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;AND&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;rating&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;PG&amp;#39;&lt;/span&gt;) &lt;span style="color:#c678dd"&gt;THEN&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Y&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ELSE&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;N&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;END&lt;/span&gt; &lt;span style="color:#e06c75"&gt;pg_actor&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;CASE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHEN&lt;/span&gt; &lt;span style="color:#c678dd"&gt;EXISTS&lt;/span&gt; (&lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film_actor&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fa&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;INNER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fa&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fa&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;actor_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;actor_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;AND&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;rating&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;NC-17&amp;#39;&lt;/span&gt;) &lt;span style="color:#c678dd"&gt;THEN&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Y&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ELSE&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;N&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;END&lt;/span&gt; &lt;span style="color:#e06c75"&gt;nc17_actor&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;actor&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#c678dd"&gt;LIKE&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;S%&amp;#39;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;OR&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#c678dd"&gt;LIKE&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;S%&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------------+-------------+---------+----------+------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;g_actor&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;pg_actor&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;nc17_actor&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------------+-------------+---------+----------+------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JOE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SWANK&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SANDRA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;KILMER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CAMERON&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;STREEP&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SANDRA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;PECK&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SISSY&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SOBIESKI&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;N&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;NICK&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;STALLONE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SEAN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;WILLIAMS&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;GROUCHO&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SINATRA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SCARLETT&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DAMON&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SPENCER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;PECK&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SEAN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;GUINESS&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SPENCER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DEPP&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SUSAN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DAVIS&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SIDNEY&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CROWE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SYLVESTER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DERN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SUSAN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DAVIS&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DAN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;STREEP&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SALMA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;NOLTE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;N&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SCARLETT&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;BENING&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JEFF&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SILVERSTONE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JOHN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SUVARI&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JAYNE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SILVERSTONE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------------+-------------+---------+----------+------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;22&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;00&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;También podemos usar &lt;code&gt;CASE&lt;/code&gt; con una subconsulta escalar. Aquí se clasifica la disponibilidad de una película según la cantidad de copias en inventario:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;title&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;CASE&lt;/span&gt; (&lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;count&lt;/span&gt;(&lt;span style="color:#56b6c2"&gt;*&lt;/span&gt;) &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;inventory&lt;/span&gt; &lt;span style="color:#e06c75"&gt;i&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;i&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHEN&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0&lt;/span&gt; &lt;span style="color:#c678dd"&gt;THEN&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Out Of Stock&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHEN&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#c678dd"&gt;THEN&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Scarce&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHEN&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2&lt;/span&gt; &lt;span style="color:#c678dd"&gt;THEN&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Scarce&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHEN&lt;/span&gt; &lt;span style="color:#d19a66"&gt;3&lt;/span&gt; &lt;span style="color:#c678dd"&gt;THEN&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Available&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHEN&lt;/span&gt; &lt;span style="color:#d19a66"&gt;4&lt;/span&gt; &lt;span style="color:#c678dd"&gt;THEN&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Available&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ELSE&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Common&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;END&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film_availability&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film&lt;/span&gt; &lt;span style="color:#e06c75"&gt;f&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; ;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-----------------------------+-------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;title&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film_availability&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-----------------------------+-------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ACADEMY&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DINOSAUR&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Common&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ACE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;GOLDFINGER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Available&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ADAPTATION&lt;/span&gt; &lt;span style="color:#e06c75"&gt;HOLES&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Available&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;AFFAIR&lt;/span&gt; &lt;span style="color:#e06c75"&gt;PREJUDICE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Common&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;AFRICAN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;EGG&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Available&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;AGENT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;TRUMAN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Common&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;AIRPLANE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SIERRA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Common&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;AIRPORT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;POLLOCK&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Available&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ALABAMA&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DEVIL&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Common&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ALADDIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CALENDAR&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Common&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ALAMO&lt;/span&gt; &lt;span style="color:#e06c75"&gt;VIDEOTAPE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Common&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ALASKA&lt;/span&gt; &lt;span style="color:#e06c75"&gt;PHANTOM&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Common&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ALI&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FOREVER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Available&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ALICE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FANTASIA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;Out&lt;/span&gt; &lt;span style="color:#c678dd"&gt;Of&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Stock&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;YOUNG&lt;/span&gt; &lt;span style="color:#c678dd"&gt;LANGUAGE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Scarce&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;YOUTH&lt;/span&gt; &lt;span style="color:#e06c75"&gt;KICK&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Scarce&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ZHIVAGO&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CORE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Scarce&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ZOOLANDER&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FICTION&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Common&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ZORRO&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ARK&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Common&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-----------------------------+-------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;1000&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;01&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="errores-de-división-por-cero"&gt;Errores de división por cero&lt;/h2&gt;
&lt;p&gt;La división por cero no está definida matemáticamente y los motores de base de datos deben tratarla como un caso especial. En MySQL, por ejemplo, una división directa entre cero puede retornar &lt;code&gt;NULL&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#d19a66"&gt;100&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;/&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;100&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;/&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NULL&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#c678dd"&gt;row&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;00&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;En reportes, un &lt;code&gt;NULL&lt;/code&gt; inesperado puede contaminar cálculos posteriores o romper supuestos del consumidor. &lt;code&gt;CASE&lt;/code&gt; permite controlar el denominador antes de ejecutar la división.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;, &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;sum&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;p&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;amount&lt;/span&gt;) &lt;span style="color:#e06c75"&gt;tot_payment_amt&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;count&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;p&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;amount&lt;/span&gt;) &lt;span style="color:#e06c75"&gt;num_payments&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;sum&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;p&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;amount&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;CASE&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHEN&lt;/span&gt; &lt;span style="color:#c678dd"&gt;count&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;p&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;amount&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0&lt;/span&gt; &lt;span style="color:#c678dd"&gt;THEN&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ELSE&lt;/span&gt; &lt;span style="color:#c678dd"&gt;count&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;p&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;amount&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;END&lt;/span&gt; &lt;span style="color:#e06c75"&gt;avg_payment&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;LEFT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;OUTER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;payment&lt;/span&gt; &lt;span style="color:#e06c75"&gt;p&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;p&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;GROUP&lt;/span&gt; &lt;span style="color:#c678dd"&gt;BY&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;, &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------------+------------+-----------------+--------------+-------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;tot_payment_amt&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;num_payments&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;avg_payment&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------------+------------+-----------------+--------------+-------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;MARY&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SMITH&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;118&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;68&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;32&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;708750&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;PATRICIA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JOHNSON&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;128&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;73&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;27&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;4&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;767778&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;LINDA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;WILLIAMS&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;135&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;74&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;26&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;5&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;220769&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;BARBARA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JONES&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;81&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;78&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;22&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;717273&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ELIZABETH&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;BROWN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;144&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;62&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;38&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;805789&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;EDUARDO&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;HIATT&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;130&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;73&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;27&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;4&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;841852&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;TERRENCE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;GUNDERSON&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;117&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;70&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;30&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;923333&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ENRIQUE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FORSYTHE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;96&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;72&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;28&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;454286&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;FREDDIE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DUGGAN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;99&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;75&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;25&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;990000&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;WADE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DELVALLE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;83&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;78&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;22&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;808182&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;AUSTIN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CINTRON&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;83&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;81&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;19&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;4&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;411053&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;------------+------------+-----------------+--------------+-------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;599&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;07&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Esta técnica evita el error o el &lt;code&gt;NULL&lt;/code&gt;, pero no siempre significa que dividir entre &lt;code&gt;1&lt;/code&gt; sea semánticamente correcto. En métricas financieras o analíticas, valida si conviene retornar &lt;code&gt;0&lt;/code&gt;, &lt;code&gt;NULL&lt;/code&gt; controlado o una etiqueta explícita.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="actualizaciones-condicionales"&gt;Actualizaciones condicionales&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;CASE&lt;/code&gt; también puede usarse dentro de &lt;code&gt;UPDATE&lt;/code&gt;. Esto permite modificar registros según reglas calculadas al momento de la escritura.&lt;/p&gt;
&lt;p&gt;El siguiente ejemplo desactiva clientes activos si su última renta ocurrió hace 90 días o más; en caso contrario, mantiene el registro activo:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;UPDATE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;SET&lt;/span&gt; &lt;span style="color:#e06c75"&gt;active&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;CASE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;WHEN&lt;/span&gt; &lt;span style="color:#d19a66"&gt;90&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;&amp;lt;=&lt;/span&gt; (&lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;datediff&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;now&lt;/span&gt;(), &lt;span style="color:#c678dd"&gt;max&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;rental_date&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental&lt;/span&gt; &lt;span style="color:#e06c75"&gt;r&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;r&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;THEN&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;ELSE&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;END&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;active&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Esta aproximación concentra la regla en una sola sentencia SQL. Antes de ejecutar un &lt;code&gt;UPDATE&lt;/code&gt; de este tipo en producción, conviene probar el mismo &lt;code&gt;CASE&lt;/code&gt; en un &lt;code&gt;SELECT&lt;/code&gt;, revisar cuántas filas cambiarán y ejecutar la operación dentro de una transacción si el motor lo permite.&lt;/p&gt;
&lt;h2 id="manejo-de-valores-null"&gt;Manejo de valores NULL&lt;/h2&gt;
&lt;p&gt;Los valores &lt;code&gt;NULL&lt;/code&gt; aparecen con frecuencia cuando usamos &lt;code&gt;LEFT OUTER JOIN&lt;/code&gt;, porque no siempre existe una fila relacionada. &lt;code&gt;CASE&lt;/code&gt; nos permite reemplazarlos por un valor controlado para reportes o interfaces.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;, &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;CASE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;WHEN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;address&lt;/span&gt; &lt;span style="color:#c678dd"&gt;IS&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NULL&lt;/span&gt; &lt;span style="color:#c678dd"&gt;THEN&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Unknown&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;ELSE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;address&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;END&lt;/span&gt; &lt;span style="color:#e06c75"&gt;address&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;CASE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;WHEN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ct&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;city&lt;/span&gt; &lt;span style="color:#c678dd"&gt;IS&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NULL&lt;/span&gt; &lt;span style="color:#c678dd"&gt;THEN&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Unknown&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;ELSE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ct&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;city&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;END&lt;/span&gt; &lt;span style="color:#e06c75"&gt;city&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;CASE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;WHEN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;cn&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;country&lt;/span&gt; &lt;span style="color:#c678dd"&gt;IS&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NULL&lt;/span&gt; &lt;span style="color:#c678dd"&gt;THEN&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Unknown&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;ELSE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;cn&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;country&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;END&lt;/span&gt; &lt;span style="color:#e06c75"&gt;country&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;LEFT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;OUTER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;address&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;address_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;address_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;LEFT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;OUTER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;city&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ct&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#e06c75"&gt;a&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;city_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ct&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;city_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;LEFT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;OUTER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;country&lt;/span&gt; &lt;span style="color:#e06c75"&gt;cn&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ct&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;country_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;cn&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;country_id&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;En varios motores también existen funciones como &lt;code&gt;COALESCE&lt;/code&gt;, útiles para este caso específico. Aun así, &lt;code&gt;CASE&lt;/code&gt; sigue siendo preferible cuando la lógica depende de más de una condición o cuando el valor de salida no es simplemente el primer dato no nulo.&lt;/p&gt;
&lt;h2 id="cierre"&gt;Cierre&lt;/h2&gt;
&lt;p&gt;La expresión &lt;code&gt;CASE&lt;/code&gt; convierte SQL en una herramienta más expresiva para preparar datos cerca de donde viven. Con ella puedes clasificar filas, derivar columnas, controlar casos límite, ejecutar actualizaciones condicionales y normalizar valores faltantes.&lt;/p&gt;
&lt;p&gt;Como regla práctica, usa &lt;code&gt;CASE&lt;/code&gt; para reglas de presentación, clasificación y cálculo que pertenecen naturalmente al resultado de la consulta. Si la lógica empieza a depender de múltiples procesos externos o de reglas de dominio altamente cambiantes, evalúa moverla a una capa de aplicación o a una vista bien documentada.&lt;/p&gt;
&lt;p&gt;En el siguiente artículo de la serie vamos a trabajar con &lt;a href="https://blog.dacadev.com/programacion/sql/04-agrupamiento-funciones-agregadas"



 


&gt;agrupamiento y funciones agregadas&lt;/a&gt;, donde &lt;code&gt;GROUP BY&lt;/code&gt;, &lt;code&gt;COUNT&lt;/code&gt;, &lt;code&gt;SUM&lt;/code&gt; y otras funciones nos permitirán resumir datos de manera consistente.&lt;/p&gt;</content:encoded></item><item><title>Estilos CSS: Posicionamiento, z-index y diseño responsive</title><link>https://blog.dacadev.com/programacion/estilos-css/posicionamiento-y-responsive/</link><pubDate>Wed, 10 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/programacion/estilos-css/posicionamiento-y-responsive/</guid><dc:creator>Dacadev</dc:creator><category>programación</category><description>Domina el posicionamiento en CSS: static, relative, absolute, fixed y sticky, los contextos de apilamiento con z-index y el diseño responsive con media queries.</description><media:content url="https://blog.dacadev.com/images/programming/html-and-css/css/05-posicionamiento-y-responsive-banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#la-propiedad-position"&gt;La propiedad position&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#fixed-anclado-al-viewport"&gt;Fixed: anclado al viewport&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#absolute-relativo-al-ancestro-posicionado"&gt;Absolute: relativo al ancestro posicionado&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#relative-desplazamiento-sin-salir-del-flujo"&gt;Relative: desplazamiento sin salir del flujo&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#sticky-lo-mejor-de-relative-y-fixed"&gt;Sticky: lo mejor de relative y fixed&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#stacking-contexts-y-z-index"&gt;Stacking contexts y z-index&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#responsive-estilos-que-se-adaptan"&gt;Responsive: estilos que se adaptan&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#media-queries"&gt;Media queries&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#breakpoints-con-mobile-first"&gt;Breakpoints con mobile first&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#estilos-para-impresión"&gt;Estilos para impresión&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#conclusión"&gt;Conclusión&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;p&gt;Hasta ahora hemos trabajado con elementos que viven en el flujo normal del documento. El posicionamiento rompe ese flujo: te permite anclar una cabecera al viewport, superponer un modal, desplegar un menú o fijar una barra lateral mientras el usuario hace scroll. Combinado con &lt;code&gt;z-index&lt;/code&gt; y las media queries, el posicionamiento es la base de las interacciones dinámicas y del diseño adaptable.&lt;/p&gt;
&lt;p&gt;Esta es la quinta entrega de la serie &lt;strong&gt;Estilos CSS&lt;/strong&gt;. Cubriremos los cinco valores de &lt;code&gt;position&lt;/code&gt;, los contextos de apilamiento con &lt;code&gt;z-index&lt;/code&gt; y los fundamentos del diseño &lt;strong&gt;responsive&lt;/strong&gt;.&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Entenderás cuándo usar cada tipo de posicionamiento, por qué &lt;code&gt;z-index&lt;/code&gt; a veces &amp;ldquo;no funciona&amp;rdquo; por culpa de los contextos de apilamiento, y cómo escribir media queries con un enfoque &lt;em&gt;mobile first&lt;/em&gt;.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="la-propiedad-position"&gt;La propiedad position&lt;/h2&gt;
&lt;p&gt;La propiedad &lt;code&gt;position&lt;/code&gt; acepta cinco valores que cambian cómo se ubica un elemento:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;static&lt;/code&gt; (por defecto) — el elemento permanece en el flujo normal.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;relative&lt;/code&gt; — se desplaza respecto a su posición original sin salir del flujo.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;absolute&lt;/code&gt; — se extrae del flujo y se posiciona respecto a su ancestro posicionado más cercano.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;fixed&lt;/code&gt; — se extrae del flujo y se posiciona respecto al viewport.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sticky&lt;/code&gt; — combina &lt;code&gt;relative&lt;/code&gt; y &lt;code&gt;fixed&lt;/code&gt; según el scroll.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Las propiedades &lt;code&gt;top&lt;/code&gt;, &lt;code&gt;right&lt;/code&gt;, &lt;code&gt;bottom&lt;/code&gt; y &lt;code&gt;left&lt;/code&gt; controlan la ubicación (y, en algunos casos, el tamaño) de los elementos posicionados.&lt;/p&gt;
&lt;h2 id="fixed-anclado-al-viewport"&gt;Fixed: anclado al viewport&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;position: fixed&lt;/code&gt; extrae el elemento del flujo normal —los demás se reorganizan como si no existiera— y lo ancla a una posición relativa al viewport, donde permanece aunque el usuario haga scroll. Es la base de los &lt;strong&gt;modales&lt;/strong&gt;: un fondo semitransparente que cubre toda la pantalla y un cuerpo centrado encima.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;modal-backdrop&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;position&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;fixed&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;top&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;; &lt;span style="color:#c678dd"&gt;right&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;; &lt;span style="color:#c678dd"&gt;bottom&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;; &lt;span style="color:#c678dd"&gt;left&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;background-color&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;rgba&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;0.5&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;modal-body&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;position&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;fixed&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;top&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;em&lt;/span&gt;; &lt;span style="color:#c678dd"&gt;bottom&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;em&lt;/span&gt;; &lt;span style="color:#c678dd"&gt;right&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;20&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;%&lt;/span&gt;; &lt;span style="color:#c678dd"&gt;left&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;20&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;%&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;background-color&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;white&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;overflow&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;auto&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



 
 





 


&lt;div class="notice tip"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z" /&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Tip&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Al posicionar no estás obligado a declarar los cuatro lados. Si omites &lt;code&gt;bottom&lt;/code&gt; y &lt;code&gt;height&lt;/code&gt;, la altura la determina el contenido de forma natural. Combinar lados con &lt;code&gt;width&lt;/code&gt;/&lt;code&gt;height&lt;/code&gt; te da control total sobre el tamaño.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="absolute-relativo-al-ancestro-posicionado"&gt;Absolute: relativo al ancestro posicionado&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;position: absolute&lt;/code&gt; también extrae el elemento del flujo, pero se posiciona respecto al primer ancestro que tenga una posición distinta de &lt;code&gt;static&lt;/code&gt;. Si ningún ancestro está posicionado, usa el &lt;em&gt;bloque contenedor inicial&lt;/em&gt; (el tamaño del viewport).&lt;/p&gt;
&lt;p&gt;Este es el patrón para colocar un botón de cierre en la esquina de un modal: el padre se marca como &lt;code&gt;position: relative&lt;/code&gt; y el botón como &lt;code&gt;position: absolute&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;modal-body&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;position&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;relative&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;modal-close&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;position&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;absolute&lt;/span&gt;; &lt;span style="color:#c678dd"&gt;top&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;0.3&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;em&lt;/span&gt;; &lt;span style="color:#c678dd"&gt;right&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;0.3&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;em&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border:1px solid #d0d0d0;border-radius:.5rem;padding:1rem;background:#fff;color:#111;margin:1rem 0;font-family:Helvetica,Arial,sans-serif;"&gt;
 &lt;div style="position:relative;background:#eaf2f8;padding:1.5em;border-radius:.4em;min-height:4em;"&gt;
 &lt;span style="position:absolute;top:.4em;right:.4em;background:#c0392b;color:#fff;padding:.2em .5em;border-radius:.3em;font-size:.8em;cursor:pointer;"&gt;✕&lt;/span&gt;
 &lt;strong&gt;Cuerpo del modal&lt;/strong&gt;
 &lt;p style="margin:.4rem 0 0;"&gt;El botón de cierre está posicionado en la esquina con &lt;code&gt;absolute&lt;/code&gt; respecto a este contenedor &lt;code&gt;relative&lt;/code&gt;.&lt;/p&gt;
 &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="relative-desplazamiento-sin-salir-del-flujo"&gt;Relative: desplazamiento sin salir del flujo&lt;/h2&gt;
&lt;p&gt;A diferencia de los anteriores, &lt;code&gt;position: relative&lt;/code&gt; &lt;strong&gt;no&lt;/strong&gt; extrae el elemento del flujo; lo traslada respecto a su posición original, dejando su hueco intacto. Tampoco permite redimensionarlo con la combinación de lados.&lt;/p&gt;
&lt;p&gt;Su uso más frecuente es establecer un &lt;strong&gt;bloque contenedor&lt;/strong&gt; para descendientes absolutos. Es la base de un menú desplegable: el contenedor es &lt;code&gt;relative&lt;/code&gt; y el menú es &lt;code&gt;absolute&lt;/code&gt;, mostrándose con &lt;code&gt;:hover&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;dropdown&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;position&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;relative&lt;/span&gt;; &lt;span style="color:#c678dd"&gt;display&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;inline-block&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;dropdown-menu&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;position&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;absolute&lt;/span&gt;; &lt;span style="color:#c678dd"&gt;top&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;100&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;%&lt;/span&gt;; &lt;span style="color:#c678dd"&gt;left&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;; &lt;span style="color:#c678dd"&gt;display&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;none&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;dropdown&lt;/span&gt;:&lt;span style="color:#61afef"&gt;hover&lt;/span&gt; .&lt;span style="color:#e5c07b"&gt;dropdown-menu&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;display&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;block&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border:1px solid #d0d0d0;border-radius:.5rem;padding:1rem;background:#fff;color:#111;margin:1rem 0;font-family:Helvetica,Arial,sans-serif;min-height:9em;"&gt;
 &lt;style&gt;
 .csdrop { position:relative; display:inline-block; }
 .csdrop-label { padding:.5em 1.5em; border:1px solid #ccc; background:#eee; cursor:pointer; border-radius:.3em; }
 .csdrop-menu { position:absolute; top:100%; left:0; min-width:160px; background:#fff; border:1px solid #999; border-radius:.3em; display:none; margin:0; padding:0; list-style:none; box-shadow:0 4px 12px rgba(0,0,0,.15); z-index:1; }
 .csdrop:hover .csdrop-menu { display:block; }
 .csdrop-menu li a { display:block; padding:.5em 1.5em; color:#2a7ae2; text-decoration:none; }
 .csdrop-menu li a:hover { background:#f0f0f0; }
 &lt;/style&gt;
 &lt;div class="csdrop"&gt;
 &lt;div class="csdrop-label"&gt;Menú principal ▾&lt;/div&gt;
 &lt;ul class="csdrop-menu"&gt;
 &lt;li&gt;&lt;a href="#posicionamiento-y-responsive"&gt;Inicio&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#posicionamiento-y-responsive"&gt;Productos&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#posicionamiento-y-responsive"&gt;Contacto&lt;/a&gt;&lt;/li&gt;
 &lt;/ul&gt;
 &lt;/div&gt;
 &lt;p style="margin:.75rem 0 0;color:#555;"&gt;Pasa el cursor sobre el botón para desplegar el menú.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="sticky-lo-mejor-de-relative-y-fixed"&gt;Sticky: lo mejor de relative y fixed&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;position: sticky&lt;/code&gt; mantiene el elemento en su posición normal hasta que, al hacer scroll, alcanza el umbral definido por &lt;code&gt;top&lt;/code&gt;/&lt;code&gt;bottom&lt;/code&gt;; en ese momento se &amp;ldquo;pega&amp;rdquo; como si fuera &lt;code&gt;fixed&lt;/code&gt;. Cuando el contenido vuelve, recupera su comportamiento relativo. Es ideal para barras laterales y cabeceras de sección que deben permanecer visibles.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;afijo&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;position&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;sticky&lt;/span&gt;; &lt;span style="color:#c678dd"&gt;top&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;em&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="stacking-contexts-y-z-index"&gt;Stacking contexts y z-index&lt;/h2&gt;
&lt;p&gt;Cuando varios elementos posicionados se solapan, &lt;code&gt;z-index&lt;/code&gt; controla el orden de apilamiento en el eje Z. Acepta enteros positivos y negativos: a mayor valor, más al frente.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;uno&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;position&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;relative&lt;/span&gt;; &lt;span style="color:#c678dd"&gt;z-index&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;dos&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;position&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;relative&lt;/span&gt;; &lt;span style="color:#c678dd"&gt;z-index&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;2&lt;/span&gt;; } &lt;span style="color:#7f848e"&gt;/* queda por encima de .uno */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Aquí está la trampa que confunde a muchos: &lt;strong&gt;cada elemento posicionado con &lt;code&gt;z-index&lt;/code&gt; crea su propio contexto de apilamiento&lt;/strong&gt;. Un hijo dentro de un contexto con &lt;code&gt;z-index: 1&lt;/code&gt; nunca podrá superar a un elemento de un contexto hermano con &lt;code&gt;z-index: 2&lt;/code&gt;, aunque el hijo tenga &lt;code&gt;z-index: 99999&lt;/code&gt;.&lt;/p&gt;




 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;&lt;code&gt;z-index&lt;/code&gt; tiene dos &amp;ldquo;gotchas&amp;rdquo;: solo funciona sobre elementos posicionados (cualquier &lt;code&gt;position&lt;/code&gt; distinto de &lt;code&gt;static&lt;/code&gt;), y al usarlo creas un nuevo contexto de apilamiento. Si un &lt;code&gt;z-index&lt;/code&gt; enorme &amp;ldquo;no funciona&amp;rdquo;, casi siempre es porque su elemento está atrapado en un contexto de apilamiento de menor prioridad.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="responsive-estilos-que-se-adaptan"&gt;Responsive: estilos que se adaptan&lt;/h2&gt;
&lt;p&gt;La enorme variedad de pantallas obliga a diseñar interfaces que respondan a distintos tamaños. La filosofía &lt;strong&gt;mobile first&lt;/strong&gt; consiste en escribir primero los estilos para móvil y luego ampliarlos progresivamente hacia tablets y escritorio.&lt;/p&gt;
&lt;h3 id="media-queries"&gt;Media queries&lt;/h3&gt;
&lt;p&gt;Una &lt;strong&gt;media query&lt;/strong&gt; aplica un bloque de CSS solo cuando se cumple una condición sobre el viewport. Conviene usar &lt;code&gt;em&lt;/code&gt; en los umbrales para que respeten el zoom y la configuración del usuario.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;@&lt;span style="color:#c678dd"&gt;media&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;(&lt;/span&gt;&lt;span style="color:#e06c75"&gt;min-width&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e06c75"&gt;35em&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;)&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e5c07b"&gt;titulo&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;font-size&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;2.25&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;rem&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Puedes combinar condiciones con lógica:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;/* AND: ambas condiciones */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;@&lt;span style="color:#c678dd"&gt;media&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;(&lt;/span&gt;&lt;span style="color:#e06c75"&gt;min-width&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e06c75"&gt;20em&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;)&lt;/span&gt; &lt;span style="color:#e06c75"&gt;and&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;(&lt;/span&gt;&lt;span style="color:#e06c75"&gt;max-width&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e06c75"&gt;35em&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;)&lt;/span&gt; { &lt;span style="color:#7f848e"&gt;/* ... */&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;/* OR: cualquiera de las dos */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;@&lt;span style="color:#c678dd"&gt;media&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;(&lt;/span&gt;&lt;span style="color:#e06c75"&gt;max-width&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e06c75"&gt;20em&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;),&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;(&lt;/span&gt;&lt;span style="color:#e06c75"&gt;min-width&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e06c75"&gt;35em&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;)&lt;/span&gt; { &lt;span style="color:#7f848e"&gt;/* ... */&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Entre las características consultables están &lt;code&gt;min-width&lt;/code&gt;, &lt;code&gt;max-width&lt;/code&gt;, &lt;code&gt;min-height&lt;/code&gt;, &lt;code&gt;orientation: landscape | portrait&lt;/code&gt; y &lt;code&gt;min-resolution: 2dppx&lt;/code&gt; (para pantallas retina). El catálogo completo está en la &lt;a href="https://developer.mozilla.org/es/docs/Web/CSS/@media"




 target="_blank"
 


&gt;documentación de &lt;code&gt;@media&lt;/code&gt; en MDN&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="breakpoints-con-mobile-first"&gt;Breakpoints con mobile first&lt;/h3&gt;
&lt;p&gt;Los &lt;strong&gt;breakpoints&lt;/strong&gt; son los puntos donde el diseño cambia de un tamaño a otro. Con el enfoque mobile first, los estilos base sirven al móvil y cada media query añade ajustes para pantallas mayores:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;titulo&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;font-size&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;1.5&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;rem&lt;/span&gt;; } &lt;span style="color:#7f848e"&gt;/* móvil (base) */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;@&lt;span style="color:#c678dd"&gt;media&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;(&lt;/span&gt;&lt;span style="color:#e06c75"&gt;min-width&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e06c75"&gt;35em&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;)&lt;/span&gt; { &lt;span style="color:#7f848e"&gt;/* tablet */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e5c07b"&gt;titulo&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;font-size&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;2&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;rem&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;@&lt;span style="color:#c678dd"&gt;media&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;(&lt;/span&gt;&lt;span style="color:#e06c75"&gt;min-width&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e06c75"&gt;50em&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;)&lt;/span&gt; { &lt;span style="color:#7f848e"&gt;/* escritorio */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e5c07b"&gt;titulo&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;font-size&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;2.5&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;rem&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border:1px solid #d0d0d0;border-radius:.5rem;padding:1rem;background:#fff;color:#111;margin:1rem 0;font-family:Helvetica,Arial,sans-serif;"&gt;
 &lt;style&gt;
 .csresp { font-size:1.5rem;font-weight:bold;color:#16828d;margin:0; }
 @media (min-width:35em) { .csresp { font-size:2rem; } }
 @media (min-width:50em) { .csresp { font-size:2.5rem; } }
 &lt;/style&gt;
 &lt;p class="csresp"&gt;Este título cambia de tamaño según el ancho&lt;/p&gt;
 &lt;small style="color:#555;"&gt;Redimensiona la ventana para cruzar los breakpoints de 35em y 50em.&lt;/small&gt;
&lt;/div&gt;
&lt;h3 id="estilos-para-impresión"&gt;Estilos para impresión&lt;/h3&gt;
&lt;p&gt;Las media queries también cubren el medio de impresión. &lt;code&gt;@media print&lt;/code&gt; aplica reglas cuando el usuario imprime o exporta a PDF:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;@&lt;span style="color:#c678dd"&gt;media&lt;/span&gt; &lt;span style="color:#e06c75"&gt;print&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;*&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;color&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;black&lt;/span&gt; &lt;span style="color:#7f848e"&gt;!important&lt;/span&gt;; &lt;span style="color:#c678dd"&gt;background&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;none&lt;/span&gt; &lt;span style="color:#7f848e"&gt;!important&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;El posicionamiento te da control fino sobre dónde vive cada elemento: &lt;code&gt;fixed&lt;/code&gt; para modales, &lt;code&gt;absolute&lt;/code&gt; para tooltips y menús, &lt;code&gt;relative&lt;/code&gt; como ancla, y &lt;code&gt;sticky&lt;/code&gt; para elementos que acompañan el scroll. Sumado a un manejo consciente de los contextos de apilamiento y a media queries con enfoque mobile first, tienes las piezas para construir interfaces dinámicas y adaptables.&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;🚀 La próxima entrega explora los &lt;strong&gt;fondos y las sombras&lt;/strong&gt;: gradientes, modos de mezcla y las propiedades &lt;code&gt;box-shadow&lt;/code&gt; y &lt;code&gt;text-shadow&lt;/code&gt; para dar profundidad a tus componentes.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
</content:encoded></item><item><title>RxJs: Operadores de combinación de observables</title><link>https://blog.dacadev.com/typescript/rxjs/operadores-combinacion-observables/</link><pubDate>Tue, 09 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/typescript/rxjs/operadores-combinacion-observables/</guid><dc:creator>Dacadev</dc:creator><category>programación</category><description>Aprende a combinar observables RxJS con startWith, endWith, concat, merge, combineLatest y forkJoin en flujos reactivos reales.</description><media:content url="https://blog.dacadev.com/images/typescript/rxjs/combination-operators/banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#startwith-inicializar-un-observable-con-una-primera-emisión"&gt;&lt;code&gt;startWith&lt;/code&gt;: inicializar un observable con una primera emisión&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#endwith-añadir-emisiones-al-completar-el-stream"&gt;&lt;code&gt;endWith&lt;/code&gt;: añadir emisiones al completar el stream&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#concat-combinar-observables-rxjs-de-forma-secuencial"&gt;&lt;code&gt;concat&lt;/code&gt;: combinar observables RxJS de forma secuencial&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#merge-combinar-emisiones-concurrentes-en-un-solo-observable"&gt;&lt;code&gt;merge&lt;/code&gt;: combinar emisiones concurrentes en un solo observable&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#combinelatest-sincronizar-los-últimos-valores-emitidos"&gt;&lt;code&gt;combineLatest&lt;/code&gt;: sincronizar los últimos valores emitidos&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#forkjoin-esperar-la-última-emisión-de-observables-finitos"&gt;&lt;code&gt;forkJoin&lt;/code&gt;: esperar la última emisión de observables finitos&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#cómo-elegir-entre-concat-merge-combinelatest-y-forkjoin"&gt;Cómo elegir entre &lt;code&gt;concat&lt;/code&gt;, &lt;code&gt;merge&lt;/code&gt;, &lt;code&gt;combineLatest&lt;/code&gt; y &lt;code&gt;forkJoin&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#conclusión"&gt;Conclusión&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;p&gt;Cuando una aplicación reactiva necesita coordinar eventos de teclado, clics, respuestas HTTP y temporizadores, el reto no está solo en crear observables, sino en decidir cómo sincronizar sus emisiones. &lt;strong&gt;Combinar observables RxJS&lt;/strong&gt; correctamente evita acoplamiento innecesario, carreras difíciles de depurar y estados intermedios inconsistentes en la interfaz.&lt;/p&gt;
&lt;p&gt;En este artículo analizaremos operadores y funciones de combinación de &lt;a href="https://rxjs.dev"




 target="_blank"
 


&gt;RxJS&lt;/a&gt;: &lt;code&gt;startWith&lt;/code&gt;, &lt;code&gt;endWith&lt;/code&gt;, &lt;code&gt;concat&lt;/code&gt;, &lt;code&gt;merge&lt;/code&gt;, &lt;code&gt;combineLatest&lt;/code&gt; y &lt;code&gt;forkJoin&lt;/code&gt;. Cada uno resuelve un problema distinto: inicializar un stream, añadir una emisión final, concatenar secuencias, mezclar eventos concurrentes, sincronizar últimos valores o esperar a que varias fuentes finalicen.&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Este artículo forma parte de la &lt;strong&gt;serie RxJs&lt;/strong&gt;. Venimos de revisar &lt;a href="https://blog.dacadev.com/typescript/operadores-no-tan-comunes-rxjs/"



 


&gt;Operadores no tan comunes&lt;/a&gt; y después continuaremos con &lt;a href="https://blog.dacadev.com/typescript/peticiones-ajax-rxjs/"



 


&gt;Ajax con RxJs&lt;/a&gt;. Aquí nos enfocamos en operadores de combinación y en cómo elegir el adecuado según el comportamiento esperado del flujo.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="startwith-inicializar-un-observable-con-una-primera-emisión"&gt;&lt;code&gt;startWith&lt;/code&gt;: inicializar un observable con una primera emisión&lt;/h2&gt;
&lt;p&gt;El operador &lt;strong&gt;&lt;code&gt;startWith&lt;/code&gt;&lt;/strong&gt; permite definir una o varias emisiones iniciales antes de que el observable fuente empiece a entregar sus propios valores. Es útil cuando una suscripción necesita un estado inicial inmediato, por ejemplo, para pintar una vista antes de que ocurra el primer evento real.&lt;/p&gt;
&lt;p&gt;En el diagrama, el valor &lt;code&gt;a&lt;/code&gt; se emite antes que cualquier valor proveniente del observable original. La suscripción no necesita esperar a que la fuente produzca el primer dato.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/combination-operators/marble-startwith_hu_3f50febfe8c561c5.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 


&lt;p&gt;Ejemplo de uso:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;of&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;startWith&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs/operators&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;numeros$&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#c678dd"&gt;of&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;2&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;).&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;startWith&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;3&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;numeros$&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;subscribe&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Este flujo primero emite &lt;code&gt;3&lt;/code&gt; por efecto de &lt;code&gt;startWith(3)&lt;/code&gt; y después continúa con las emisiones de &lt;code&gt;of(1, 2, 3)&lt;/code&gt;. En escenarios de UI, este patrón suele aparecer cuando necesitas mostrar un valor por defecto antes de recibir eventos del usuario o datos remotos.&lt;/p&gt;




 
 





 


&lt;div class="notice tip"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z" /&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Tip&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;&lt;code&gt;startWith&lt;/code&gt; no modifica la fuente original; crea un nuevo observable con emisiones prefijadas. Esta distinción mantiene la composición declarativa del pipeline.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="endwith-añadir-emisiones-al-completar-el-stream"&gt;&lt;code&gt;endWith&lt;/code&gt;: añadir emisiones al completar el stream&lt;/h2&gt;
&lt;p&gt;El operador &lt;strong&gt;&lt;code&gt;endWith&lt;/code&gt;&lt;/strong&gt; trabaja en el extremo opuesto de &lt;code&gt;startWith&lt;/code&gt;. En lugar de emitir valores al inicio, agrega emisiones al final, justo cuando el observable fuente completa.&lt;/p&gt;
&lt;p&gt;Esto implica una condición importante: la fuente debe completar. Si el observable nunca envía la señal de &lt;code&gt;complete&lt;/code&gt;, &lt;code&gt;endWith&lt;/code&gt; no tendrá oportunidad de emitir sus valores finales.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/combination-operators/marble-endwith_hu_1dbaa30bd447d3be.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 


&lt;p&gt;El modo de uso puede combinar ambos operadores:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;of&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;startWith&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;endWith&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs/operators&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;numeros$&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#c678dd"&gt;of&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;2&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;).&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;startWith&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;a&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;b&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;c&amp;#39;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;endWith&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;x&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;y&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;z&amp;#39;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;numeros$&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;subscribe&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El resultado incluye las emisiones iniciales, los valores originales y las emisiones finales:&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/combination-operators/console-start-endwith_hu_2d98486731811f2a.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 


&lt;p&gt;&lt;code&gt;endWith&lt;/code&gt; es apropiado para flujos finitos donde quieres señalar un cierre lógico, adjuntar un marcador final o emitir un estado de terminación después de procesar una secuencia.&lt;/p&gt;
&lt;h2 id="concat-combinar-observables-rxjs-de-forma-secuencial"&gt;&lt;code&gt;concat&lt;/code&gt;: combinar observables RxJS de forma secuencial&lt;/h2&gt;
&lt;p&gt;La función &lt;strong&gt;&lt;code&gt;concat&lt;/code&gt;&lt;/strong&gt; concatena observables uno detrás de otro. Se suscribe al primer observable, espera a que complete y solo entonces avanza al siguiente. El resultado es un observable nuevo que conserva el orden secuencial de las fuentes.&lt;/p&gt;




 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;&lt;code&gt;concat&lt;/code&gt; es una función de creación/combinación; no debe confundirse con &lt;code&gt;concatMap&lt;/code&gt;. &lt;code&gt;concatMap&lt;/code&gt; proyecta cada emisión hacia un observable interno y los aplana en orden. &lt;code&gt;concat&lt;/code&gt;, en cambio, recibe fuentes ya definidas y las ejecuta secuencialmente.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;El diagrama muestra que las emisiones del segundo stream no empiezan hasta que el primero completa. Esta propiedad es crítica cuando el orden tiene semántica de negocio, por ejemplo, inicializar una configuración antes de consumir un flujo dependiente.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/combination-operators/marble-concat_hu_ee64538cd07c1214.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 


&lt;p&gt;Su modo de uso es:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;concat&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;interval&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;take&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs/operators&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;intervalo$&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;interval&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;1000&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;concat&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;intervalo$&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;take&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;2&lt;/span&gt;)),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;intervalo$&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;take&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;3&lt;/span&gt;)),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;2&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;5&lt;/span&gt;] &lt;span style="color:#7f848e"&gt;// un iterable u objeto compatible con ObservableInput
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;).&lt;span style="color:#e06c75"&gt;subscribe&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El primer &lt;code&gt;intervalo$.pipe(take(2))&lt;/code&gt; emite dos valores y completa. Después se ejecuta el segundo &lt;code&gt;intervalo$.pipe(take(3))&lt;/code&gt;. Finalmente, &lt;code&gt;concat&lt;/code&gt; consume el arreglo &lt;code&gt;[1, 2, 3, 5]&lt;/code&gt; como una fuente compatible con &lt;code&gt;ObservableInput&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;El resultado respeta ese orden:&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/combination-operators/console-concat_hu_4f320d74fd3067a2.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 


&lt;p&gt;La restricción operativa más importante es que cada fuente debe completar para que &lt;code&gt;concat&lt;/code&gt; avance. Si el primer observable es infinito, el segundo nunca se suscribirá.&lt;/p&gt;
&lt;h2 id="merge-combinar-emisiones-concurrentes-en-un-solo-observable"&gt;&lt;code&gt;merge&lt;/code&gt;: combinar emisiones concurrentes en un solo observable&lt;/h2&gt;
&lt;p&gt;La función &lt;strong&gt;&lt;code&gt;merge&lt;/code&gt;&lt;/strong&gt; combina las emisiones de dos o más observables en un único stream de salida. A diferencia de &lt;code&gt;concat&lt;/code&gt;, no espera a que una fuente complete para suscribirse a la siguiente; todas las fuentes activas pueden emitir de forma concurrente.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;merge&lt;/code&gt; completa únicamente cuando todos los observables de entrada han completado. En streams de eventos del DOM, como &lt;code&gt;click&lt;/code&gt; o &lt;code&gt;keyup&lt;/code&gt;, esto normalmente significa que el flujo permanece activo durante toda la vida de la página, salvo que se aplique una estrategia de finalización explícita.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/combination-operators/marble-merge_hu_2109f797e699b06b.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 


&lt;p&gt;Modo de uso:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;fromEvent&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;merge&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;pluck&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs/operators&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;keyup$&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fromEvent&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;document&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;keyup&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;click$&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fromEvent&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;document&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;click&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;merge&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;keyup$&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;pluck&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;type&amp;#39;&lt;/span&gt;)),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;click$&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;pluck&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;type&amp;#39;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;).&lt;span style="color:#e06c75"&gt;subscribe&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;En este caso, ambos observables se transforman para emitir únicamente el tipo de evento. El stream resultante recibe tanto &lt;code&gt;keyup&lt;/code&gt; como &lt;code&gt;click&lt;/code&gt;, sin imponer un orden artificial entre ellos.&lt;/p&gt;
&lt;p&gt;El resultado en consola evidencia que ambos eventos se combinan en una sola suscripción:&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/combination-operators/console-merge-events_hu_13a76b79f5c14923.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 






 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;&lt;code&gt;merge&lt;/code&gt; es una buena elección cuando las fuentes son independientes y quieres reaccionar a cualquiera de ellas con la misma lógica de downstream.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="combinelatest-sincronizar-los-últimos-valores-emitidos"&gt;&lt;code&gt;combineLatest&lt;/code&gt;: sincronizar los últimos valores emitidos&lt;/h2&gt;
&lt;p&gt;La función &lt;strong&gt;&lt;code&gt;combineLatest&lt;/code&gt;&lt;/strong&gt; combina múltiples observables y emite un arreglo con el último valor disponible de cada fuente. Su comportamiento tiene una regla clave: no emite hasta que todos los observables participantes hayan emitido al menos una vez.&lt;/p&gt;
&lt;p&gt;Después de esa primera sincronización, cada nueva emisión de cualquier fuente produce una nueva salida con el valor actualizado de esa fuente y los últimos valores conocidos de las demás. Esto es especialmente útil para formularios, filtros, coordenadas de UI y estados derivados.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/combination-operators/marble-combinelatest_hu_5536863cb22096a9.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 


&lt;p&gt;El código de uso puede ser parecido a esto:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;combineLatest&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;fromEvent&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;pluck&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs/operators&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;input1&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;document&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;createElement&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;input&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;input2&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;document&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;createElement&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;input&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;input1&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;placeholder&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;email@example.com&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;input2&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;placeholder&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;*******&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;input2&lt;/span&gt;.&lt;span style="color:#c678dd"&gt;type&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;password&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e5c07b"&gt;document&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;querySelector&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;body&amp;#39;&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;?&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;append&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;input1&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;input2&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// helper
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;getInputString&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;elem&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;HTMLElement&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fromEvent&lt;/span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;KeyboardEvent&lt;/span&gt;&amp;gt;(&lt;span style="color:#e06c75"&gt;elem&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;keyup&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;pluck&lt;/span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;KeyboardEvent&lt;/span&gt;&amp;gt;(&lt;span style="color:#98c379"&gt;&amp;#39;target&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;value&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; );
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;combineLatest&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;getInputString&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;input1&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;getInputString&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;input2&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;).&lt;span style="color:#e06c75"&gt;subscribe&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El ejemplo conserva la firma posicional usada durante mucho tiempo en RxJS. En código moderno, especialmente con RxJS 7+, suele preferirse la firma con arreglo porque escala mejor y es más explícita:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;combineLatest&lt;/span&gt;([
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;getInputString&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;input1&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;getInputString&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;input2&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;]).&lt;span style="color:#e06c75"&gt;subscribe&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;También conviene considerar que &lt;code&gt;pluck&lt;/code&gt; pertenece a un estilo más antiguo de transformación. Para proyectos nuevos, &lt;code&gt;map&lt;/code&gt; con acceso explícito suele ser más legible y compatible con la evolución del ecosistema.&lt;/p&gt;




 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Si una de las fuentes de &lt;code&gt;combineLatest&lt;/code&gt; nunca emite, el observable combinado tampoco emitirá. Para evitar estados bloqueados, puedes inicializar fuentes con &lt;code&gt;startWith&lt;/code&gt; cuando tenga sentido semántico.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="forkjoin-esperar-la-última-emisión-de-observables-finitos"&gt;&lt;code&gt;forkJoin&lt;/code&gt;: esperar la última emisión de observables finitos&lt;/h2&gt;
&lt;p&gt;La función &lt;strong&gt;&lt;code&gt;forkJoin&lt;/code&gt;&lt;/strong&gt; emite una sola vez con la última emisión de cada observable de entrada, pero únicamente cuando todos completan. Este comportamiento la convierte en una herramienta precisa para coordinar operaciones finitas, como peticiones HTTP simultáneas.&lt;/p&gt;




 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Los observables pasados a &lt;code&gt;forkJoin&lt;/code&gt; deben ser finitos. Si alguno nunca completa, &lt;code&gt;forkJoin&lt;/code&gt; nunca emitirá resultado.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;El diagrama muestra que la salida aparece al final, cuando todas las fuentes han completado y existe un último valor para cada una.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/combination-operators/marble-forkjoin_hu_21713f02bc2dcb9.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 


&lt;p&gt;Modo de uso:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;of&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;interval&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;forkJoin&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;take&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;delay&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs/operators&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;numeros$&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#c678dd"&gt;of&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;2&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;4&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;intervalo$&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;interval&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;1000&lt;/span&gt;).&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;take&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;3&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;letras$&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#c678dd"&gt;of&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;a&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;b&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;c&amp;#39;&lt;/span&gt;).&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;delay&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;3500&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// forkJoin(
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// numeros$,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// intervalo$,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// letras$
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// ).subscribe(console.log);
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// forkJoin(
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// numeros$,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// intervalo$,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// letras$
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// ).subscribe(resp =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// console.log(&amp;#39;numeros&amp;#39;, resp[0]);
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// console.log(&amp;#39;intervalo&amp;#39;, resp[1]);
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// console.log(&amp;#39;letras&amp;#39;, resp[2]);
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// });
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// forkJoin({
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// numeros$,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// intervalo$,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// letras$
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// }).subscribe(resp =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// console.log(resp);
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// });
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;forkJoin&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;num&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;numeros$&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;int&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;intervalo$&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;let&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e06c75"&gt;letras$&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}).&lt;span style="color:#e06c75"&gt;subscribe&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;resp&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;resp&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La forma con objeto es especialmente práctica porque conserva nombres semánticos en la respuesta. En lugar de depender de índices como &lt;code&gt;resp[0]&lt;/code&gt;, &lt;code&gt;resp[1]&lt;/code&gt; o &lt;code&gt;resp[2]&lt;/code&gt;, el consumidor trabaja con propiedades explícitas: &lt;code&gt;num&lt;/code&gt;, &lt;code&gt;int&lt;/code&gt; y &lt;code&gt;let&lt;/code&gt;.&lt;/p&gt;




 
 





 


&lt;div class="notice tip"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z" /&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Tip&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;El uso más común de &lt;code&gt;forkJoin&lt;/code&gt; aparece cuando haces peticiones AJAX simultáneas y necesitas continuar solo cuando todas han terminado correctamente.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="cómo-elegir-entre-concat-merge-combinelatest-y-forkjoin"&gt;Cómo elegir entre &lt;code&gt;concat&lt;/code&gt;, &lt;code&gt;merge&lt;/code&gt;, &lt;code&gt;combineLatest&lt;/code&gt; y &lt;code&gt;forkJoin&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Estos operadores pueden parecer similares porque todos combinan fuentes, pero su semántica de tiempo es distinta:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Usa &lt;strong&gt;&lt;code&gt;concat&lt;/code&gt;&lt;/strong&gt; cuando el orden secuencial sea obligatorio y cada fuente deba completar antes de iniciar la siguiente.&lt;/li&gt;
&lt;li&gt;Usa &lt;strong&gt;&lt;code&gt;merge&lt;/code&gt;&lt;/strong&gt; cuando las fuentes sean independientes y quieras reaccionar a cualquiera de ellas tan pronto como emita.&lt;/li&gt;
&lt;li&gt;Usa &lt;strong&gt;&lt;code&gt;combineLatest&lt;/code&gt;&lt;/strong&gt; cuando necesites calcular estado derivado a partir del último valor conocido de varias fuentes activas.&lt;/li&gt;
&lt;li&gt;Usa &lt;strong&gt;&lt;code&gt;forkJoin&lt;/code&gt;&lt;/strong&gt; cuando esperes observables finitos y solo necesites el resultado final de cada uno.&lt;/li&gt;
&lt;li&gt;Usa &lt;strong&gt;&lt;code&gt;startWith&lt;/code&gt;&lt;/strong&gt; y &lt;strong&gt;&lt;code&gt;endWith&lt;/code&gt;&lt;/strong&gt; para insertar emisiones de inicio o cierre dentro de un pipeline.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Esta elección tiene impacto directo en latencia, orden de ejecución y condiciones de completado. En sistemas reactivos, estos detalles definen si el flujo se mantiene responsivo o si queda bloqueado esperando una emisión que nunca llega.&lt;/p&gt;
&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;Combinar observables RxJS requiere distinguir entre concurrencia, secuencialidad y sincronización de valores. &lt;code&gt;concat&lt;/code&gt; serializa fuentes, &lt;code&gt;merge&lt;/code&gt; las mezcla, &lt;code&gt;combineLatest&lt;/code&gt; deriva estado desde los últimos valores y &lt;code&gt;forkJoin&lt;/code&gt; espera resultados finales de observables finitos.&lt;/p&gt;
&lt;p&gt;Dominar estas diferencias permite diseñar pipelines más predecibles y expresivos. En el siguiente artículo aplicaremos estos conceptos al trabajo con peticiones AJAX, donde &lt;code&gt;forkJoin&lt;/code&gt;, &lt;code&gt;mergeMap&lt;/code&gt; y otros operadores empiezan a interactuar con latencia real de red y manejo de errores.&lt;/p&gt;</content:encoded></item><item><title>Estilos CSS: Layouts con Float, Flexbox y Grid</title><link>https://blog.dacadev.com/programacion/estilos-css/layouts-flexbox-grid/</link><pubDate>Mon, 08 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/programacion/estilos-css/layouts-flexbox-grid/</guid><dc:creator>Dacadev</dc:creator><category>programación</category><description>Aprende a maquetar con CSS: el legado de float y clearfix, el modelo flexible de Flexbox y el sistema bidimensional de CSS Grid, con demostraciones renderizadas.</description><media:content url="https://blog.dacadev.com/images/programming/html-and-css/css/04-layouts-flexbox-grid-banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#float-el-origen-y-el-clearfix"&gt;Float: el origen y el clearfix&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#flexbox-layout-en-una-dimensión"&gt;Flexbox: layout en una dimensión&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#alinear-ítems-con-justify-content-y-align-items"&gt;Alinear ítems con justify-content y align-items&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#controlar-el-tamaño-flex-grow-flex-shrink-y-flex-basis"&gt;Controlar el tamaño: flex-grow, flex-shrink y flex-basis&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#dirección-y-envoltura"&gt;Dirección y envoltura&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#propiedades-del-ítem"&gt;Propiedades del ítem&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#css-grid-layout-en-dos-dimensiones"&gt;CSS Grid: layout en dos dimensiones&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#una-rejilla-básica"&gt;Una rejilla básica&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#posicionar-ítems-por-líneas"&gt;Posicionar ítems por líneas&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#áreas-con-nombre"&gt;Áreas con nombre&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#rejilla-implícita-y-galerías-responsivas"&gt;Rejilla implícita y galerías responsivas&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#flexbox-y-grid-complementarios-no-rivales"&gt;Flexbox y Grid: complementarios, no rivales&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#conclusión"&gt;Conclusión&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;p&gt;Maquetar es componer la estructura visual de una página: columnas, rejillas, barras laterales, galerías. Durante años se hizo con herramientas que no se diseñaron para ello —&lt;code&gt;float&lt;/code&gt; nació para envolver texto alrededor de imágenes— hasta que llegaron &lt;strong&gt;Flexbox&lt;/strong&gt; y &lt;strong&gt;CSS Grid&lt;/strong&gt;, dos sistemas pensados específicamente para layout. Conocer los tres te permite entender el código heredado y elegir la herramienta correcta para cada problema.&lt;/p&gt;
&lt;p&gt;Esta es la cuarta entrega de la serie &lt;strong&gt;Estilos CSS&lt;/strong&gt;. Recorreremos &lt;code&gt;float&lt;/code&gt; y la técnica &lt;code&gt;clearfix&lt;/code&gt;, el modelo unidimensional de Flexbox y el sistema bidimensional de Grid, con ejemplos que puedes ver renderizados.&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Aprenderás cuándo sigue siendo útil &lt;code&gt;float&lt;/code&gt;, cómo controlar el tamaño de los ítems con &lt;code&gt;flex&lt;/code&gt;, y cómo posicionar elementos en una rejilla con &lt;code&gt;grid-template&lt;/code&gt;.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="float-el-origen-y-el-clearfix"&gt;Float: el origen y el clearfix&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;float&lt;/code&gt; extrae un elemento del flujo normal y lo desplaza hacia un lado de su contenedor; el contenido adyacente fluye a su alrededor. Ese fue su propósito original: envolver texto alrededor de una imagen.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;imagen&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;float&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;left&lt;/span&gt;; &lt;span style="color:#c678dd"&gt;margin-right&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;em&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border:1px solid #d0d0d0;border-radius:.5rem;padding:1rem 1.25rem;background:#fff;color:#111;margin:1rem 0;font-family:Helvetica,Arial,sans-serif;"&gt;
 &lt;div style="float:left;width:90px;height:90px;background:#2a9da9;color:#fff;display:flex;align-items:center;justify-content:center;border-radius:.4em;margin:0 1em .5em 0;"&gt;float&lt;/div&gt;
 &lt;p style="margin:0;"&gt;Este párrafo fluye alrededor del bloque flotado. El texto se ajusta al margen del elemento extraído del flujo, exactamente el caso de uso para el que &lt;code&gt;float&lt;/code&gt; fue concebido: envolver contenido alrededor de una figura.&lt;/p&gt;
 &lt;div style="clear:both;"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Cuando usas &lt;code&gt;float&lt;/code&gt;, necesitas &lt;strong&gt;limpiar&lt;/strong&gt; el flujo para que el contenedor vuelva a comportarse con normalidad. El patrón estándar es el &lt;strong&gt;clearfix&lt;/strong&gt;, implementado con un pseudo-elemento:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;clearfix&lt;/span&gt;::&lt;span style="color:#61afef"&gt;before&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;clearfix&lt;/span&gt;::&lt;span style="color:#61afef"&gt;after&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;display&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;table&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;content&lt;/span&gt;: &lt;span style="color:#98c379"&gt;&amp;#34; &amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;clearfix&lt;/span&gt;::&lt;span style="color:#61afef"&gt;after&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;clear&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;both&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



 
 





 


&lt;div class="notice tip"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z" /&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Tip&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Para layouts modernos, &lt;code&gt;float&lt;/code&gt; casi siempre se reemplaza por Flexbox o Grid. Resérvalo para su propósito original: envolver texto alrededor de un elemento.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="flexbox-layout-en-una-dimensión"&gt;Flexbox: layout en una dimensión&lt;/h2&gt;
&lt;p&gt;Al aplicar &lt;code&gt;display: flex&lt;/code&gt; a un contenedor, este se convierte en un &lt;strong&gt;flex container&lt;/strong&gt; y sus hijos en &lt;strong&gt;flex items&lt;/strong&gt;. Flexbox organiza los ítems a lo largo de un eje principal y los alinea en el eje transversal, ajustando tamaños de forma flexible.&lt;/p&gt;
&lt;p&gt;Un contenedor flex tiene dos ejes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Eje principal (main)&lt;/strong&gt; — la dirección en la que se colocan los ítems (horizontal por defecto).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Eje transversal (cross)&lt;/strong&gt; — perpendicular al principal.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="alinear-ítems-con-justify-content-y-align-items"&gt;Alinear ítems con justify-content y align-items&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;justify-content&lt;/code&gt; controla la distribución a lo largo del &lt;strong&gt;eje principal&lt;/strong&gt;: &lt;code&gt;flex-start&lt;/code&gt;, &lt;code&gt;flex-end&lt;/code&gt;, &lt;code&gt;center&lt;/code&gt;, &lt;code&gt;space-between&lt;/code&gt;, &lt;code&gt;space-around&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;align-items&lt;/code&gt; controla la alineación en el &lt;strong&gt;eje transversal&lt;/strong&gt;: &lt;code&gt;stretch&lt;/code&gt; (por defecto), &lt;code&gt;flex-start&lt;/code&gt;, &lt;code&gt;flex-end&lt;/code&gt;, &lt;code&gt;center&lt;/code&gt;, &lt;code&gt;baseline&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;barra&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;display&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;flex&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;justify-content&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;space-between&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;align-items&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;center&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border:1px solid #d0d0d0;border-radius:.5rem;padding:1rem;background:#fff;color:#111;margin:1rem 0;font-family:Helvetica,Arial,sans-serif;"&gt;
 &lt;div style="display:flex;justify-content:space-between;align-items:center;background:#eaf2f8;padding:.75rem;border-radius:.4em;"&gt;
 &lt;span style="background:#2a9da9;color:#fff;padding:.5em 1em;border-radius:.3em;"&gt;Logo&lt;/span&gt;
 &lt;span style="background:#2a9da9;color:#fff;padding:.5em 1em;border-radius:.3em;"&gt;Menú&lt;/span&gt;
 &lt;span style="background:#2a9da9;color:#fff;padding:.5em 1em;border-radius:.3em;"&gt;Perfil&lt;/span&gt;
 &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="controlar-el-tamaño-flex-grow-flex-shrink-y-flex-basis"&gt;Controlar el tamaño: flex-grow, flex-shrink y flex-basis&lt;/h3&gt;
&lt;p&gt;La propiedad abreviada &lt;code&gt;flex&lt;/code&gt; agrupa tres propiedades que gobiernan el tamaño de cada ítem:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;flex-basis&lt;/code&gt;&lt;/strong&gt; — el tamaño base (de partida) del ítem antes de crecer o encoger. Su valor inicial es &lt;code&gt;auto&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;flex-grow&lt;/code&gt;&lt;/strong&gt; — el factor de crecimiento para repartir el espacio sobrante. &lt;code&gt;0&lt;/code&gt; no crece.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;flex-shrink&lt;/code&gt;&lt;/strong&gt; — el factor de encogimiento cuando falta espacio.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;col-a&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;flex&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;; } &lt;span style="color:#7f848e"&gt;/* crece para ocupar el espacio sobrante */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;col-b&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;flex&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;2&lt;/span&gt;; } &lt;span style="color:#7f848e"&gt;/* crece al doble que col-a */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border:1px solid #d0d0d0;border-radius:.5rem;padding:1rem;background:#fff;color:#111;margin:1rem 0;font-family:Helvetica,Arial,sans-serif;"&gt;
 &lt;div style="display:flex;gap:.5rem;"&gt;
 &lt;div style="flex:1;background:#2a9da9;color:#fff;padding:1em;border-radius:.4em;text-align:center;"&gt;flex: 1&lt;/div&gt;
 &lt;div style="flex:2;background:#16828d;color:#fff;padding:1em;border-radius:.4em;text-align:center;"&gt;flex: 2 (el doble de ancho)&lt;/div&gt;
 &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="dirección-y-envoltura"&gt;Dirección y envoltura&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;flex-direction&lt;/code&gt; cambia el eje principal: &lt;code&gt;row&lt;/code&gt; (por defecto), &lt;code&gt;row-reverse&lt;/code&gt;, &lt;code&gt;column&lt;/code&gt;, &lt;code&gt;column-reverse&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;flex-wrap&lt;/code&gt; permite que los ítems salten a una nueva línea cuando no caben: &lt;code&gt;nowrap&lt;/code&gt; (por defecto), &lt;code&gt;wrap&lt;/code&gt;, &lt;code&gt;wrap-reverse&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;flex-flow&lt;/code&gt; es la abreviatura de ambas: &lt;code&gt;flex-flow: row wrap&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="propiedades-del-ítem"&gt;Propiedades del ítem&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;align-self&lt;/code&gt; — sobrescribe &lt;code&gt;align-items&lt;/code&gt; para un ítem concreto.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;order&lt;/code&gt; — reordena los ítems sin tocar el HTML; el valor inicial es &lt;code&gt;0&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;




 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Flexbox crea automáticamente columnas de igual altura y es la herramienta ideal para centrar un elemento. Para un catálogo de bugs conocidos y sus soluciones, consulta &lt;a href="https://github.com/philipwalton/flexbugs"




 target="_blank"
 


&gt;flexbugs&lt;/a&gt;.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="css-grid-layout-en-dos-dimensiones"&gt;CSS Grid: layout en dos dimensiones&lt;/h2&gt;
&lt;p&gt;Mientras Flexbox trabaja en un solo eje, &lt;strong&gt;CSS Grid&lt;/strong&gt; organiza el contenido en &lt;strong&gt;filas y columnas&lt;/strong&gt; simultáneamente. Antes de usarlo conviene fijar su vocabulario:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Grid line&lt;/strong&gt; — las líneas que forman la estructura de la rejilla.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Grid track&lt;/strong&gt; — el espacio entre dos líneas adyacentes (una fila o una columna).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Grid cell&lt;/strong&gt; — la intersección de una fila y una columna.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Grid area&lt;/strong&gt; — un rectángulo formado por una o más celdas.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="una-rejilla-básica"&gt;Una rejilla básica&lt;/h3&gt;
&lt;p&gt;Se activa con &lt;code&gt;display: grid&lt;/code&gt; y se definen las pistas con &lt;code&gt;grid-template-columns&lt;/code&gt; y &lt;code&gt;grid-template-rows&lt;/code&gt;. La unidad &lt;code&gt;fr&lt;/code&gt; representa una fracción del espacio disponible.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;grid&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;display&lt;/span&gt;: &lt;span style="color:#c678dd"&gt;grid&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;grid-template-columns&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;&lt;span style="color:#e06c75"&gt;fr&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;&lt;span style="color:#e06c75"&gt;fr&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;&lt;span style="color:#e06c75"&gt;fr&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;gap&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;0.5&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;em&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border:1px solid #d0d0d0;border-radius:.5rem;padding:1rem;background:#fff;color:#111;margin:1rem 0;font-family:Helvetica,Arial,sans-serif;"&gt;
 &lt;div style="display:grid;grid-template-columns:1fr 1fr 1fr;gap:.5em;"&gt;
 &lt;div style="background:#2a9da9;color:#fff;padding:1.5em;border-radius:.4em;text-align:center;"&gt;a&lt;/div&gt;
 &lt;div style="background:#2a9da9;color:#fff;padding:1.5em;border-radius:.4em;text-align:center;"&gt;b&lt;/div&gt;
 &lt;div style="background:#2a9da9;color:#fff;padding:1.5em;border-radius:.4em;text-align:center;"&gt;c&lt;/div&gt;
 &lt;div style="background:#2a9da9;color:#fff;padding:1.5em;border-radius:.4em;text-align:center;"&gt;d&lt;/div&gt;
 &lt;div style="background:#2a9da9;color:#fff;padding:1.5em;border-radius:.4em;text-align:center;"&gt;e&lt;/div&gt;
 &lt;div style="background:#2a9da9;color:#fff;padding:1.5em;border-radius:.4em;text-align:center;"&gt;f&lt;/div&gt;
 &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;La función &lt;code&gt;repeat()&lt;/code&gt; evita la repetición: &lt;code&gt;grid-template-columns: repeat(3, 1fr)&lt;/code&gt; equivale a &lt;code&gt;1fr 1fr 1fr&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="posicionar-ítems-por-líneas"&gt;Posicionar ítems por líneas&lt;/h3&gt;
&lt;p&gt;Cada línea de la rejilla tiene un número. Con &lt;code&gt;grid-column&lt;/code&gt; y &lt;code&gt;grid-row&lt;/code&gt; indicas dónde empieza y termina un ítem usando la sintaxis &lt;code&gt;inicio / fin&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;destacado&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;grid-column&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;/&lt;/span&gt; &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;; &lt;span style="color:#7f848e"&gt;/* abarca de la línea 1 a la 3 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;grid-row&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;span&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2&lt;/span&gt;; &lt;span style="color:#7f848e"&gt;/* abarca dos pistas verticales */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border:1px solid #d0d0d0;border-radius:.5rem;padding:1rem;background:#fff;color:#111;margin:1rem 0;font-family:Helvetica,Arial,sans-serif;"&gt;
 &lt;div style="display:grid;grid-template-columns:repeat(3,1fr);grid-auto-rows:60px;gap:.5em;"&gt;
 &lt;div style="grid-column:1 / 3;background:#f39c12;color:#fff;display:flex;align-items:center;justify-content:center;border-radius:.4em;"&gt;grid-column: 1 / 3&lt;/div&gt;
 &lt;div style="background:#2a9da9;color:#fff;display:flex;align-items:center;justify-content:center;border-radius:.4em;"&gt;b&lt;/div&gt;
 &lt;div style="background:#2a9da9;color:#fff;display:flex;align-items:center;justify-content:center;border-radius:.4em;"&gt;c&lt;/div&gt;
 &lt;div style="background:#2a9da9;color:#fff;display:flex;align-items:center;justify-content:center;border-radius:.4em;"&gt;d&lt;/div&gt;
 &lt;div style="background:#2a9da9;color:#fff;display:flex;align-items:center;justify-content:center;border-radius:.4em;"&gt;e&lt;/div&gt;
 &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="áreas-con-nombre"&gt;Áreas con nombre&lt;/h3&gt;
&lt;p&gt;La forma más legible de componer un layout es nombrar las áreas con &lt;code&gt;grid-template-areas&lt;/code&gt; y asignar cada elemento con &lt;code&gt;grid-area&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;contenedor&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;display&lt;/span&gt;: &lt;span style="color:#c678dd"&gt;grid&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;grid-template-areas&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;titulo titulo&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;nav nav&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;main aside&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;grid-template-columns&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;2&lt;/span&gt;&lt;span style="color:#e06c75"&gt;fr&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;&lt;span style="color:#e06c75"&gt;fr&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;gap&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;em&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;header&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;grid-area&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;titulo&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;nav&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;grid-area&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;nav&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;main&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;grid-area&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;main&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;aside&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;grid-area&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;aside&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border:1px solid #d0d0d0;border-radius:.5rem;padding:1rem;background:#fff;color:#111;margin:1rem 0;font-family:Helvetica,Arial,sans-serif;"&gt;
 &lt;div style="display:grid;grid-template-areas:'titulo titulo' 'nav nav' 'main aside';grid-template-columns:2fr 1fr;gap:.5em;"&gt;
 &lt;div style="grid-area:titulo;background:#16828d;color:#fff;padding:.8em;border-radius:.4em;text-align:center;"&gt;titulo&lt;/div&gt;
 &lt;div style="grid-area:nav;background:#1f6f78;color:#fff;padding:.8em;border-radius:.4em;text-align:center;"&gt;nav&lt;/div&gt;
 &lt;div style="grid-area:main;background:#2a9da9;color:#fff;padding:1.5em;border-radius:.4em;text-align:center;"&gt;main&lt;/div&gt;
 &lt;div style="grid-area:aside;background:#f39c12;color:#fff;padding:1.5em;border-radius:.4em;text-align:center;"&gt;aside&lt;/div&gt;
 &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="rejilla-implícita-y-galerías-responsivas"&gt;Rejilla implícita y galerías responsivas&lt;/h3&gt;
&lt;p&gt;Cuando no conoces de antemano la cantidad de ítems —por ejemplo, datos que vienen de una API— la &lt;strong&gt;rejilla implícita&lt;/strong&gt; crece automáticamente para acomodarlos. La combinación de &lt;code&gt;auto-fill&lt;/code&gt; con &lt;code&gt;minmax()&lt;/code&gt; produce galerías que se adaptan al ancho disponible sin media queries:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;galeria&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;display&lt;/span&gt;: &lt;span style="color:#c678dd"&gt;grid&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;grid-template-columns&lt;/span&gt;: &lt;span style="color:#61afef;font-weight:bold"&gt;repeat&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;auto&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;fill&lt;/span&gt;, &lt;span style="color:#61afef;font-weight:bold"&gt;minmax&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;180&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;px&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;&lt;span style="color:#e06c75"&gt;fr&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;gap&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;em&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border:1px solid #d0d0d0;border-radius:.5rem;padding:1rem;background:#fff;color:#111;margin:1rem 0;font-family:Helvetica,Arial,sans-serif;"&gt;
 &lt;div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:.5em;"&gt;
 &lt;div style="background:#2a9da9;color:#fff;padding:1.2em;border-radius:.4em;text-align:center;"&gt;1&lt;/div&gt;
 &lt;div style="background:#2a9da9;color:#fff;padding:1.2em;border-radius:.4em;text-align:center;"&gt;2&lt;/div&gt;
 &lt;div style="background:#2a9da9;color:#fff;padding:1.2em;border-radius:.4em;text-align:center;"&gt;3&lt;/div&gt;
 &lt;div style="background:#2a9da9;color:#fff;padding:1.2em;border-radius:.4em;text-align:center;"&gt;4&lt;/div&gt;
 &lt;div style="background:#2a9da9;color:#fff;padding:1.2em;border-radius:.4em;text-align:center;"&gt;5&lt;/div&gt;
 &lt;/div&gt;
 &lt;small style="display:block;margin-top:.5rem;color:#555;"&gt;Redimensiona la ventana: las columnas se reorganizan solas.&lt;/small&gt;
&lt;/div&gt;




 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Con Grid solo puedes formar rectángulos. No se pueden crear formas en L o U directamente; se simulan dejando celdas vacías (con &lt;code&gt;.&lt;/code&gt; en &lt;code&gt;grid-template-areas&lt;/code&gt;) o combinando áreas.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="flexbox-y-grid-complementarios-no-rivales"&gt;Flexbox y Grid: complementarios, no rivales&lt;/h2&gt;
&lt;p&gt;No tienes que elegir uno. La combinación más potente es usar &lt;strong&gt;Grid&lt;/strong&gt; para la estructura macro de la página (cabecera, contenido, barra lateral, pie) y &lt;strong&gt;Flexbox&lt;/strong&gt; para alinear el contenido dentro de cada zona (una barra de navegación, una tarjeta, un grupo de botones).&lt;/p&gt;
&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;float&lt;/code&gt; resuelve el envolvimiento de texto; Flexbox domina el layout en una dimensión y el centrado; Grid organiza estructuras bidimensionales complejas. Elegir la herramienta adecuada para cada problema —y combinarlas— es lo que distingue una maquetación robusta de una llena de parches.&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;🚀 En la próxima entrega abordamos el &lt;strong&gt;posicionamiento&lt;/strong&gt; (&lt;code&gt;relative&lt;/code&gt;, &lt;code&gt;absolute&lt;/code&gt;, &lt;code&gt;fixed&lt;/code&gt;, &lt;code&gt;sticky&lt;/code&gt;), los contextos de apilamiento con &lt;code&gt;z-index&lt;/code&gt; y el diseño &lt;strong&gt;responsive&lt;/strong&gt; con media queries.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
</content:encoded></item><item><title>SQL: Filtrado de Datos con la Cláusula WHERE</title><link>https://blog.dacadev.com/programacion/sql/02-filtrado-datos-clausula-where/</link><pubDate>Mon, 08 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/programacion/sql/02-filtrado-datos-clausula-where/</guid><dc:creator>Dacadev</dc:creator><category>programación</category><description>Aprende filtrado de datos con WHERE en SQL usando operadores, BETWEEN, IN, LIKE, expresiones regulares y NULL.</description><media:content url="https://blog.dacadev.com/images/programming/sql/filtering/banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#la-cláusula-where-y-las-condiciones-booleanas"&gt;La cláusula WHERE y las condiciones booleanas&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#condiciones-de-igualdad"&gt;Condiciones de igualdad&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#condiciones-de-desigualdad"&gt;Condiciones de desigualdad&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#modificación-de-datos-con-condiciones-de-igualdad"&gt;Modificación de datos con condiciones de igualdad&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#condiciones-de-rango"&gt;Condiciones de rango&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#usando-between"&gt;Usando BETWEEN&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#condiciones-de-pertenencia-con-in"&gt;Condiciones de pertenencia con IN&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#subconsultas-dentro-de-in"&gt;Subconsultas dentro de IN&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#condiciones-de-coincidencia-con-like"&gt;Condiciones de coincidencia con LIKE&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#expresiones-regulares"&gt;Expresiones regulares&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#filtrado-de-valores-null"&gt;Filtrado de valores NULL&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#cierre"&gt;Cierre&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;p&gt;El &lt;strong&gt;filtrado de datos en SQL&lt;/strong&gt; es una operación diaria cuando trabajas con bases relacionales: rara vez necesitas todas las filas de una tabla. La &lt;strong&gt;cláusula WHERE&lt;/strong&gt; expresa condiciones precisas para reducir resultados, evitar lecturas innecesarias y alinear la consulta con la lógica de negocio. Este es el artículo #2 de la serie SQL; si necesitas repasar &lt;code&gt;SELECT&lt;/code&gt;, &lt;code&gt;FROM&lt;/code&gt; y el modelo general de consulta, revisa &lt;a href="https://blog.dacadev.com/programacion/sql/01-fundamentos-sql-select-from-where"



 


&gt;Fundamentos de SQL&lt;/a&gt;.&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Aprenderás a usar &lt;code&gt;WHERE&lt;/code&gt; con igualdad, desigualdad, rangos, &lt;code&gt;BETWEEN&lt;/code&gt;, &lt;code&gt;IN&lt;/code&gt;, subconsultas, &lt;code&gt;LIKE&lt;/code&gt;, expresiones regulares y &lt;code&gt;NULL&lt;/code&gt;, tanto en lectura como en modificación.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="la-cláusula-where-y-las-condiciones-booleanas"&gt;La cláusula WHERE y las condiciones booleanas&lt;/h2&gt;
&lt;p&gt;La cláusula &lt;code&gt;WHERE&lt;/code&gt; filtra filas evaluando una o más condiciones. Cada condición produce un resultado lógico que el motor de base de datos usa para decidir si una fila entra o no en el resultado final.&lt;/p&gt;
&lt;p&gt;En la práctica, esas condiciones suelen combinar varios tipos de operadores:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Operadores de comparación&lt;/strong&gt;: &lt;code&gt;=&lt;/code&gt;, &lt;code&gt;!=&lt;/code&gt;, &lt;code&gt;&amp;lt;&lt;/code&gt;, &lt;code&gt;&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;, &lt;code&gt;LIKE&lt;/code&gt;, &lt;code&gt;IN&lt;/code&gt;, &lt;code&gt;BETWEEN&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Operadores aritméticos&lt;/strong&gt;: &lt;code&gt;+&lt;/code&gt;, &lt;code&gt;-&lt;/code&gt;, &lt;code&gt;*&lt;/code&gt;, &lt;code&gt;/&lt;/code&gt;, cuando necesitas comparar expresiones calculadas.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Operadores lógicos&lt;/strong&gt;: &lt;code&gt;AND&lt;/code&gt;, &lt;code&gt;OR&lt;/code&gt;, &lt;code&gt;NOT&lt;/code&gt;, para componer filtros más específicos.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Aunque &lt;code&gt;WHERE&lt;/code&gt; es el punto central para filtrar filas, también existe &lt;code&gt;HAVING&lt;/code&gt;, que se utiliza después de agrupar datos con &lt;code&gt;GROUP BY&lt;/code&gt;. La diferencia es importante: &lt;code&gt;WHERE&lt;/code&gt; filtra filas antes de la agregación; &lt;code&gt;HAVING&lt;/code&gt; filtra grupos después de calcular agregados.&lt;/p&gt;
&lt;h2 id="condiciones-de-igualdad"&gt;Condiciones de igualdad&lt;/h2&gt;
&lt;p&gt;La condición de igualdad compara una columna contra una expresión. Esa expresión puede ser un literal, un número, una fecha o incluso el resultado de una subconsulta.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;title&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;RIVER OUTLAW&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;fed_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;111-11-1111&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;amount&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;375&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;25&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; (&lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film_id&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;title&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;RIVER OUTLAW&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Observemos un caso concreto usando la base de datos de ejemplo Sakila. La consulta obtiene los correos de clientes que rentaron películas el &lt;code&gt;2005-06-14&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;email&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;INNER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental&lt;/span&gt; &lt;span style="color:#e06c75"&gt;r&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;r&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;date&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;r&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;rental_date&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;2005-06-14&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------------------------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;email&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------------------------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CATHERINE&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;CAMPBELL&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;@&lt;/span&gt;&lt;span style="color:#e06c75"&gt;sakilacustomer&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;org&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;JOYCE&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;EDWARDS&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;@&lt;/span&gt;&lt;span style="color:#e06c75"&gt;sakilacustomer&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;org&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;TERRENCE&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;GUNDERSON&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;@&lt;/span&gt;&lt;span style="color:#e06c75"&gt;sakilacustomer&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;org&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------------------------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;16&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;03&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Aquí &lt;code&gt;date(r.rental_date)&lt;/code&gt; transforma el &lt;code&gt;DATETIME&lt;/code&gt; a fecha antes de comparar. En producción, aplicar funciones sobre columnas puede limitar el uso eficiente de índices.&lt;/p&gt;
&lt;h2 id="condiciones-de-desigualdad"&gt;Condiciones de desigualdad&lt;/h2&gt;
&lt;p&gt;La desigualdad expresa el caso contrario: queremos excluir filas que coinciden con un valor. En SQL puedes escribirla con &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;, &lt;code&gt;!=&lt;/code&gt; o usando &lt;code&gt;NOT&lt;/code&gt; según el motor y el estilo del equipo.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;email&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;INNER&lt;/span&gt; &lt;span style="color:#c678dd"&gt;JOIN&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental&lt;/span&gt; &lt;span style="color:#e06c75"&gt;r&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;ON&lt;/span&gt; &lt;span style="color:#c678dd"&gt;c&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;r&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;date&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;r&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;rental_date&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;2005-06-14&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-----------------------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;email&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-----------------------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;AUSTIN&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;CINTRON&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;@&lt;/span&gt;&lt;span style="color:#e06c75"&gt;sakilacustomer&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;org&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;AUSTIN&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;CINTRON&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;@&lt;/span&gt;&lt;span style="color:#e06c75"&gt;sakilacustomer&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;org&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;AUSTIN&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;CINTRON&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;@&lt;/span&gt;&lt;span style="color:#e06c75"&gt;sakilacustomer&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;org&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;AUSTIN&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;CINTRON&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;@&lt;/span&gt;&lt;span style="color:#e06c75"&gt;sakilacustomer&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;org&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-----------------------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;16028&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;03&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La diferencia semántica es directa: en lugar de seleccionar rentas del día indicado, excluimos ese día.&lt;/p&gt;
&lt;h2 id="modificación-de-datos-con-condiciones-de-igualdad"&gt;Modificación de datos con condiciones de igualdad&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;WHERE&lt;/code&gt; no solo aparece en &lt;code&gt;SELECT&lt;/code&gt;. También es crítico en &lt;code&gt;UPDATE&lt;/code&gt; y &lt;code&gt;DELETE&lt;/code&gt;, donde define exactamente qué filas serán modificadas o eliminadas.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;DELETE&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#c678dd"&gt;year&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;rental_date&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2004&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;DELETE&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#c678dd"&gt;year&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;rental_date&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2005&lt;/span&gt; &lt;span style="color:#c678dd"&gt;AND&lt;/span&gt; &lt;span style="color:#c678dd"&gt;year&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;rental_date&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2006&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El primer caso elimina rentas del año 2004; el segundo elimina rentas que no pertenecen ni a 2005 ni a 2006.&lt;/p&gt;




 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Antes de ejecutar un &lt;code&gt;DELETE&lt;/code&gt; o &lt;code&gt;UPDATE&lt;/code&gt; con &lt;code&gt;WHERE&lt;/code&gt;, valida la condición con un &lt;code&gt;SELECT&lt;/code&gt; equivalente. Un filtro demasiado amplio puede modificar más filas de las esperadas.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="condiciones-de-rango"&gt;Condiciones de rango&lt;/h2&gt;
&lt;p&gt;Para filtrar rangos puedes combinar operadores como &lt;code&gt;&amp;lt;&lt;/code&gt;, &lt;code&gt;&amp;lt;=&lt;/code&gt;, &lt;code&gt;&amp;gt;&lt;/code&gt; y &lt;code&gt;&amp;gt;=&lt;/code&gt; con &lt;code&gt;AND&lt;/code&gt; u &lt;code&gt;OR&lt;/code&gt;. Esto funciona con fechas, números y otros tipos comparables.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;rental_date&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental_date&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;2005-05-25&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+---------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental_date&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+---------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;130&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2005&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;05&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;24&lt;/span&gt; &lt;span style="color:#d19a66"&gt;22&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;53&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;30&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;459&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2005&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;05&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;24&lt;/span&gt; &lt;span style="color:#d19a66"&gt;22&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;54&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;33&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;239&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2005&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;05&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;24&lt;/span&gt; &lt;span style="color:#d19a66"&gt;23&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;31&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;46&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+---------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;8&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;00&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;rental_date&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental_date&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;&amp;lt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;2005-06-16&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;AND&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental_date&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;&amp;gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;2005-06-14&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+---------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental_date&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+---------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;416&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2005&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;06&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;14&lt;/span&gt; &lt;span style="color:#d19a66"&gt;22&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;53&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;33&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;516&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2005&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;06&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;14&lt;/span&gt; &lt;span style="color:#d19a66"&gt;22&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;55&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;13&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;148&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2005&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;06&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;15&lt;/span&gt; &lt;span style="color:#d19a66"&gt;23&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;20&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;26&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;237&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2005&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;06&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;15&lt;/span&gt; &lt;span style="color:#d19a66"&gt;23&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;36&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;37&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;155&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2005&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;06&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;15&lt;/span&gt; &lt;span style="color:#d19a66"&gt;23&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;55&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;27&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;341&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2005&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;06&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;15&lt;/span&gt; &lt;span style="color:#d19a66"&gt;23&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;57&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;20&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;149&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2005&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;06&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;15&lt;/span&gt; &lt;span style="color:#d19a66"&gt;23&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;58&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;53&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+---------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;364&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;00&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="usando-between"&gt;Usando BETWEEN&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;BETWEEN&lt;/code&gt; permite expresar un rango con una sintaxis más compacta. El valor menor va a la izquierda, el mayor a la derecha, y ambos límites son inclusivos.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;rental_date&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental_date&lt;/span&gt; &lt;span style="color:#c678dd"&gt;BETWEEN&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;2005-06-14&amp;#39;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;AND&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;2005-06-16&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+---------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental_date&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+---------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;416&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2005&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;06&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;14&lt;/span&gt; &lt;span style="color:#d19a66"&gt;22&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;53&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;33&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;516&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2005&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;06&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;14&lt;/span&gt; &lt;span style="color:#d19a66"&gt;22&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;55&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;13&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;148&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2005&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;06&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;15&lt;/span&gt; &lt;span style="color:#d19a66"&gt;23&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;20&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;26&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;237&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2005&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;06&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;15&lt;/span&gt; &lt;span style="color:#d19a66"&gt;23&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;36&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;37&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;155&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2005&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;06&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;15&lt;/span&gt; &lt;span style="color:#d19a66"&gt;23&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;55&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;27&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;341&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2005&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;06&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;15&lt;/span&gt; &lt;span style="color:#d19a66"&gt;23&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;57&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;20&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;149&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2005&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;06&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;-&lt;/span&gt;&lt;span style="color:#d19a66"&gt;15&lt;/span&gt; &lt;span style="color:#d19a66"&gt;23&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;58&lt;/span&gt;:&lt;span style="color:#d19a66"&gt;53&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+---------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;364&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;00&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



 
 





 


&lt;div class="notice tip"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z" /&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Tip&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;&lt;code&gt;BETWEEN&lt;/code&gt; puede usarse con fechas, horas, números y &lt;code&gt;strings&lt;/code&gt;. Recuerda que los límites son inclusivos, así que valida cuidadosamente rangos de tiempo cuando trabajes con columnas &lt;code&gt;DATETIME&lt;/code&gt;.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="condiciones-de-pertenencia-con-in"&gt;Condiciones de pertenencia con IN&lt;/h2&gt;
&lt;p&gt;Las condiciones de pertenencia permiten verificar si un valor existe dentro de una lista. Primero, analicemos la versión con &lt;code&gt;OR&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;title&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;rating&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rating&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;G&amp;#39;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;OR&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rating&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;PG&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------------------------+--------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;title&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rating&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------------------------+--------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ACADEMY&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DINOSAUR&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;PG&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ACE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;GOLDFINGER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;G&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;WEDDING&lt;/span&gt; &lt;span style="color:#e06c75"&gt;APOLLO&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;PG&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;WEREWOLF&lt;/span&gt; &lt;span style="color:#e06c75"&gt;LOLA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;G&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;WEST&lt;/span&gt; &lt;span style="color:#e06c75"&gt;LION&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;G&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;YOUNG&lt;/span&gt; &lt;span style="color:#c678dd"&gt;LANGUAGE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;G&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------------------------+--------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;372&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;00&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La misma condición puede escribirse de forma más clara con &lt;code&gt;IN&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;title&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;rating&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rating&lt;/span&gt; &lt;span style="color:#c678dd"&gt;IN&lt;/span&gt; (&lt;span style="color:#98c379"&gt;&amp;#39;G&amp;#39;&lt;/span&gt;,&lt;span style="color:#98c379"&gt;&amp;#39;PG&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;También puedes combinar pertenencia y negación usando &lt;code&gt;NOT IN&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;title&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;rating&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rating&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NOT&lt;/span&gt; &lt;span style="color:#c678dd"&gt;IN&lt;/span&gt; (&lt;span style="color:#98c379"&gt;&amp;#39;PG-13&amp;#39;&lt;/span&gt;,&lt;span style="color:#98c379"&gt;&amp;#39;R&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;NC-17&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;IN&lt;/code&gt; mejora la legibilidad cuando comparas una columna contra múltiples valores discretos y evita repetir la misma columna.&lt;/p&gt;
&lt;h2 id="subconsultas-dentro-de-in"&gt;Subconsultas dentro de IN&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;IN&lt;/code&gt; no está limitado a listas escritas manualmente. También puedes usar una subconsulta para calcular dinámicamente los valores válidos de comparación.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;title&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;rating&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rating&lt;/span&gt; &lt;span style="color:#c678dd"&gt;IN&lt;/span&gt; (&lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rating&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;film&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;title&lt;/span&gt; &lt;span style="color:#c678dd"&gt;LIKE&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;%PET%&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------------------------+--------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;title&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rating&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------------------------+--------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ACADEMY&lt;/span&gt; &lt;span style="color:#e06c75"&gt;DINOSAUR&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;PG&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ACE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;GOLDFINGER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;G&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;WEDDING&lt;/span&gt; &lt;span style="color:#e06c75"&gt;APOLLO&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;PG&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;WEREWOLF&lt;/span&gt; &lt;span style="color:#e06c75"&gt;LOLA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;G&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;WEST&lt;/span&gt; &lt;span style="color:#e06c75"&gt;LION&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;G&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;YOUNG&lt;/span&gt; &lt;span style="color:#c678dd"&gt;LANGUAGE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#c678dd"&gt;G&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;---------------------------+--------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;372&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;00&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La subconsulta obtiene los &lt;code&gt;rating&lt;/code&gt; de películas cuyo título contiene &lt;code&gt;PET&lt;/code&gt;; la consulta externa recupera las películas con esos ratings.&lt;/p&gt;
&lt;h2 id="condiciones-de-coincidencia-con-like"&gt;Condiciones de coincidencia con LIKE&lt;/h2&gt;
&lt;p&gt;Las condiciones de coincidencia permiten buscar patrones de texto en lugar de valores exactos. Con &lt;code&gt;LIKE&lt;/code&gt;, SQL ofrece dos comodines principales:&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Comodín&lt;/th&gt;
 &lt;th&gt;Significado&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;_&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Exactamente un carácter&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;%&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Cualquier cantidad de caracteres, incluyendo cero&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Consideremos este patrón: &lt;code&gt;_A_T%S&lt;/code&gt;. Significa: un carácter cualquiera, luego &lt;code&gt;A&lt;/code&gt;, luego un carácter cualquiera, luego &lt;code&gt;T&lt;/code&gt;, luego cualquier secuencia, y finalmente &lt;code&gt;S&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#c678dd"&gt;LIKE&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;_A_T%S&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-----------+------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-----------+------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;MATTHEWS&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ERICA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;WALTERS&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CASSANDRA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;WATTS&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SHELLY&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-----------+------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;3&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;00&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;LIKE&lt;/code&gt; es útil para búsquedas simples. Un patrón que inicia con &lt;code&gt;%&lt;/code&gt;, como &lt;code&gt;'%PET%'&lt;/code&gt;, suele ser más costoso porque limita el uso de índices tradicionales.&lt;/p&gt;
&lt;h2 id="expresiones-regulares"&gt;Expresiones regulares&lt;/h2&gt;
&lt;p&gt;Algunos motores permiten filtrar texto con expresiones regulares. En MySQL, por ejemplo, se usa &lt;code&gt;REGEXP&lt;/code&gt;. Otros motores tienen variantes propias, así que siempre valida la sintaxis de tu base de datos.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#e06c75"&gt;REGEXP&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;^[QY]&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;last_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;first_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;YOUNG&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;CYNTHIA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;QUALLS&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;STEPHEN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;QUINTANILLA&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ROGER&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;YANEZ&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;LUIS&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;YEE&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;MARVIN&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;QUIGLEY&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;TROY&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-------------+------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;6&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;16&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El patrón &lt;code&gt;^[QY]&lt;/code&gt; indica que el apellido debe iniciar con &lt;code&gt;Q&lt;/code&gt; o &lt;code&gt;Y&lt;/code&gt;. Las expresiones regulares son más expresivas que &lt;code&gt;LIKE&lt;/code&gt;, pero menos portables entre motores.&lt;/p&gt;
&lt;h2 id="filtrado-de-valores-null"&gt;Filtrado de valores NULL&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;NULL&lt;/code&gt; es un caso especial en SQL. No representa &lt;code&gt;false&lt;/code&gt;, cero ni una cadena vacía; representa ausencia de valor o valor desconocido. Por esa razón, no debes comparar &lt;code&gt;NULL&lt;/code&gt; con &lt;code&gt;=&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Para consultar valores nulos se usa &lt;code&gt;IS NULL&lt;/code&gt;, y para excluirlos se usa &lt;code&gt;IS NOT NULL&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mysql&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;SELECT&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental_id&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;FROM&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;WHERE&lt;/span&gt; &lt;span style="color:#e06c75"&gt;return_date&lt;/span&gt; &lt;span style="color:#c678dd"&gt;IS&lt;/span&gt; &lt;span style="color:#c678dd"&gt;NULL&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-----------+-------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;rental_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e06c75"&gt;customer_id&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-----------+-------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;11496&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;155&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;11541&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;335&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;15867&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;505&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;15875&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;41&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;15894&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;168&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;15966&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#d19a66"&gt;374&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;+&lt;/span&gt;&lt;span style="color:#7f848e"&gt;-----------+-------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d19a66"&gt;183&lt;/span&gt; &lt;span style="color:#c678dd"&gt;rows&lt;/span&gt; &lt;span style="color:#c678dd"&gt;in&lt;/span&gt; &lt;span style="color:#c678dd"&gt;set&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;.&lt;span style="color:#d19a66"&gt;01&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;&lt;code&gt;NULL = NULL&lt;/code&gt; no se evalúa como verdadero en SQL estándar. Cuando una comparación involucra &lt;code&gt;NULL&lt;/code&gt;, el resultado puede ser desconocido; por eso &lt;code&gt;IS NULL&lt;/code&gt; y &lt;code&gt;IS NOT NULL&lt;/code&gt; son operadores específicos para este caso.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="cierre"&gt;Cierre&lt;/h2&gt;
&lt;p&gt;La cláusula &lt;code&gt;WHERE&lt;/code&gt; convierte una tabla completa en un conjunto de filas relevante. Dominar igualdad, desigualdad, rangos, pertenencia, patrones y &lt;code&gt;NULL&lt;/code&gt; te permite escribir consultas más precisas y seguras.&lt;/p&gt;
&lt;p&gt;Como regla práctica, diseña filtros explícitos, valida condiciones destructivas con &lt;code&gt;SELECT&lt;/code&gt;, y considera el impacto de funciones, comodines y expresiones regulares sobre los índices. En el siguiente artículo abordaremos &lt;a href="https://blog.dacadev.com/programacion/sql/03-logica-condicional-case"



 


&gt;Lógica condicional con CASE&lt;/a&gt;, una herramienta clave para transformar valores dentro de tus consultas.&lt;/p&gt;</content:encoded></item><item><title>RxJs: Operadores no tan comunes</title><link>https://blog.dacadev.com/typescript/rxjs/operadores-no-tan-comunes-rxjs/</link><pubDate>Sun, 07 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/typescript/rxjs/operadores-no-tan-comunes-rxjs/</guid><dc:creator>Dacadev</dc:creator><category>programación</category><description>Aprende operadores rxjs menos frecuentes como take, first, takeWhile, takeUntil, skip, distinct y distinctUntilChanged.</description><media:content url="https://blog.dacadev.com/images/typescript/rxjs/uncommon-operators/banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#take-limitar-emisiones-de-un-observable"&gt;&lt;code&gt;take&lt;/code&gt;: limitar emisiones de un Observable&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#first-tomar-la-primera-emisión-o-la-primera-que-cumpla-una-condición"&gt;&lt;code&gt;first&lt;/code&gt;: tomar la primera emisión o la primera que cumpla una condición&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#first-con-predicado"&gt;&lt;code&gt;first&lt;/code&gt; con predicado&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#takewhile-emitir-mientras-se-mantenga-una-condición"&gt;&lt;code&gt;takeWhile&lt;/code&gt;: emitir mientras se mantenga una condición&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#takeuntil-cancelar-un-flujo-con-otro-observable"&gt;&lt;code&gt;takeUntil&lt;/code&gt;: cancelar un flujo con otro Observable&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#skip-omitir-emisiones-iniciales"&gt;&lt;code&gt;skip&lt;/code&gt;: omitir emisiones iniciales&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#distinct-eliminar-valores-repetidos-globalmente"&gt;&lt;code&gt;distinct&lt;/code&gt;: eliminar valores repetidos globalmente&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#distinct-con-selector-para-objetos"&gt;&lt;code&gt;distinct&lt;/code&gt; con selector para objetos&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#distinctuntilchanged-evitar-repeticiones-consecutivas"&gt;&lt;code&gt;distinctUntilChanged&lt;/code&gt;: evitar repeticiones consecutivas&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#distinctuntilchanged-con-comparador"&gt;&lt;code&gt;distinctUntilChanged&lt;/code&gt; con comparador&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#distinctuntilkeychanged-comparación-consecutiva-por-propiedad"&gt;&lt;code&gt;distinctUntilKeyChanged&lt;/code&gt;: comparación consecutiva por propiedad&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#conclusión"&gt;Conclusión&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;p&gt;En flujos reactivos de interfaz, temporizadores o eventos del DOM, no siempre necesitas transformar cada emisión. Con frecuencia el problema operativo consiste en limitar una suscripción, cancelar un &lt;code&gt;Observable&lt;/code&gt; ante una señal externa o eliminar emisiones repetidas. Estos &lt;strong&gt;operadores RxJS&lt;/strong&gt; resuelven ese tipo de control sin introducir estado mutable adicional ni lógica imperativa alrededor de la suscripción.&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Este artículo forma parte de la &lt;strong&gt;serie RxJs&lt;/strong&gt;. Venimos de revisar &lt;a href="https://blog.dacadev.com/typescript/operadores-de-transformacion-rxjs/"



 


&gt;operadores de transformación&lt;/a&gt; y aquí analizaremos &lt;code&gt;take&lt;/code&gt;, &lt;code&gt;first&lt;/code&gt;, &lt;code&gt;takeWhile&lt;/code&gt;, &lt;code&gt;takeUntil&lt;/code&gt;, &lt;code&gt;skip&lt;/code&gt;, &lt;code&gt;distinct&lt;/code&gt;, &lt;code&gt;distinctUntilChanged&lt;/code&gt; y &lt;code&gt;distinctUntilKeyChanged&lt;/code&gt;. El siguiente artículo aborda los &lt;a href="https://blog.dacadev.com/typescript/operadores-combinacion-observables/"



 


&gt;operadores de combinación&lt;/a&gt;.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;La referencia formal de estos operadores está en la documentación oficial de &lt;a href="https://rxjs.dev"




 target="_blank"
 


&gt;RxJS&lt;/a&gt; y en el modelo conceptual de &lt;a href="https://reactivex.io"




 target="_blank"
 


&gt;ReactiveX&lt;/a&gt;. En este artículo nos concentraremos en su comportamiento práctico, especialmente en cuándo completan el flujo y cómo comparan valores.&lt;/p&gt;
&lt;h2 id="take-limitar-emisiones-de-un-observable"&gt;&lt;code&gt;take&lt;/code&gt;: limitar emisiones de un Observable&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;take&lt;/code&gt; permite definir cuántas emisiones del &lt;code&gt;Observable&lt;/code&gt; fuente queremos recibir. Una vez alcanza ese límite, el operador completa la cadena y cancela la suscripción aguas arriba.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/uncommon-operators/marble-take_hu_18c316156fc7352b.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 


&lt;p&gt;Este patrón es útil cuando el consumidor solo necesita una muestra finita de un flujo potencialmente largo, como los primeros eventos, los primeros valores de un intervalo o una respuesta inicial.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;of&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;rxjs&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;take&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;tap&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;rxjs/operators&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;numeros$&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#c678dd"&gt;of&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;2&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;4&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;5&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;numeros$&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;tap&lt;/span&gt;((&lt;span style="color:#e06c75"&gt;valor&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;tap&amp;#34;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;valor&lt;/span&gt;)),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;take&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;3&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e06c75"&gt;subscribe&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;next&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;valor&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;next&amp;#34;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;valor&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;complete&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; () &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;complete&amp;#34;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El &lt;code&gt;tap&lt;/code&gt; se ejecuta solo para los valores que alcanzan la suscripción antes de que &lt;code&gt;take(3)&lt;/code&gt; complete el flujo.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/uncommon-operators/console-take_hu_acbd9bad5d1f147f.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 






 
 





 


&lt;div class="notice tip"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z" /&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Tip&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;&lt;code&gt;take&lt;/code&gt; es una forma declarativa de evitar suscripciones más largas de lo necesario. En flujos infinitos como &lt;code&gt;interval&lt;/code&gt;, puede prevenir fugas si el ciclo de vida esperado es finito.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="first-tomar-la-primera-emisión-o-la-primera-que-cumpla-una-condición"&gt;&lt;code&gt;first&lt;/code&gt;: tomar la primera emisión o la primera que cumpla una condición&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;first&lt;/code&gt; obtiene la primera emisión del &lt;code&gt;Observable&lt;/code&gt; y completa la suscripción. Su caso básico se parece a &lt;code&gt;take(1)&lt;/code&gt;, pero también acepta un predicado para esperar la primera emisión que cumpla una condición.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/uncommon-operators/marble-first_hu_b57c6c3a31077d9a.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 


&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;fromEvent&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;rxjs&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;first&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;rxjs/operators&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;click$&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fromEvent&lt;/span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;PointerEvent&lt;/span&gt;&amp;gt;(&lt;span style="color:#e5c07b"&gt;document&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#34;click&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;click$&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;first&lt;/span&gt;()).&lt;span style="color:#e06c75"&gt;subscribe&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;next&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;event&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;next&amp;#34;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;event&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;complete&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; () &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;complete&amp;#34;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Después del primer clic, el flujo completa y deja de escuchar nuevos eventos.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/uncommon-operators/console-first_hu_7c4360a367784e09.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 


&lt;h3 id="first-con-predicado"&gt;&lt;code&gt;first&lt;/code&gt; con predicado&lt;/h3&gt;
&lt;p&gt;Cuando &lt;code&gt;first&lt;/code&gt; recibe un predicado, ignora las emisiones previas hasta encontrar la primera que devuelva &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;fromEvent&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;rxjs&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;first&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;tap&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;rxjs/operators&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;click$&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fromEvent&lt;/span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;PointerEvent&lt;/span&gt;&amp;gt;(&lt;span style="color:#e5c07b"&gt;document&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#34;click&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;click$&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;tap&lt;/span&gt;(() &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;tap&amp;#34;&lt;/span&gt;)),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;first&lt;/span&gt;((&lt;span style="color:#e06c75"&gt;event&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;event&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;clientY&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;&amp;gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;150&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e06c75"&gt;subscribe&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;next&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;event&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;next&amp;#34;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;event&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;complete&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; () &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;complete&amp;#34;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El &lt;code&gt;tap&lt;/code&gt; confirma que el flujo sigue recibiendo clics, pero &lt;code&gt;first&lt;/code&gt; solo emite cuando la coordenada &lt;code&gt;clientY&lt;/code&gt; cumple la condición.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/uncommon-operators/console-first-predicate_hu_dd483944bae9057f.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 






 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Si la fuente completa sin que el predicado de &lt;code&gt;first&lt;/code&gt; se cumpla, RxJS puede emitir un error &lt;code&gt;EmptyError&lt;/code&gt;. Considera un valor por defecto o un operador alternativo cuando ese escenario sea válido.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="takewhile-emitir-mientras-se-mantenga-una-condición"&gt;&lt;code&gt;takeWhile&lt;/code&gt;: emitir mientras se mantenga una condición&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;takeWhile&lt;/code&gt; mantiene la suscripción activa mientras el predicado devuelva &lt;code&gt;true&lt;/code&gt;. En cuanto una emisión no cumple la condición, el operador completa el flujo.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/uncommon-operators/marble-takewhile_hu_e42f671167cc2913.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 


&lt;p&gt;En este ejemplo tomamos clics mientras la coordenada &lt;code&gt;y&lt;/code&gt; sea menor o igual a &lt;code&gt;150&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;fromEvent&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;rxjs&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;map&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;takeWhile&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;rxjs/operators&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;click$&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fromEvent&lt;/span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;PointerEvent&lt;/span&gt;&amp;gt;(&lt;span style="color:#e5c07b"&gt;document&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#34;click&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;click$&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;map&lt;/span&gt;(({ &lt;span style="color:#e06c75"&gt;x&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;y&lt;/span&gt; }) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; ({ &lt;span style="color:#e06c75"&gt;x&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;y&lt;/span&gt; })),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;takeWhile&lt;/span&gt;(({ &lt;span style="color:#e06c75"&gt;y&lt;/span&gt; }) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;&amp;lt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;150&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;true&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e06c75"&gt;subscribe&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;next&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;coords&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;next&amp;#34;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;coords&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;complete&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; () &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;complete&amp;#34;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El segundo argumento, conocido como bandera &lt;strong&gt;inclusive&lt;/strong&gt;, indica si la emisión que rompe la condición también debe enviarse al suscriptor. Por defecto es &lt;code&gt;false&lt;/code&gt;; con &lt;code&gt;true&lt;/code&gt;, el valor que provoca el cierre se conserva.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/uncommon-operators/console-takewhile-inclusive_hu_e080f0a7ac2ad474.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 






 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;&lt;code&gt;takeWhile&lt;/code&gt; modela límites basados en datos. Es diferente de &lt;code&gt;filter&lt;/code&gt;: &lt;code&gt;filter&lt;/code&gt; descarta valores y continúa; &lt;code&gt;takeWhile&lt;/code&gt; completa el flujo cuando la condición deja de cumplirse.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="takeuntil-cancelar-un-flujo-con-otro-observable"&gt;&lt;code&gt;takeUntil&lt;/code&gt;: cancelar un flujo con otro Observable&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;takeUntil&lt;/code&gt; recibe un segundo &lt;code&gt;Observable&lt;/code&gt;, llamado normalmente &lt;code&gt;notifier&lt;/code&gt;. El flujo principal emite hasta que ese &lt;code&gt;notifier&lt;/code&gt; produce su primera emisión; en ese momento la cadena completa.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/uncommon-operators/marble-takeuntil_hu_cdc0acc3e1676e92.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 


&lt;p&gt;Este patrón es común para cancelar intervalos, peticiones, listeners o cualquier proceso reactivo asociado al ciclo de vida de un componente.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;fromEvent&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;interval&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;rxjs&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;takeUntil&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;rxjs/operators&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;boton&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;document&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;createElement&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;button&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;boton&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;innerHTML&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;Detener timing&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e5c07b"&gt;document&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;querySelector&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;body&amp;#34;&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;?&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;append&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;boton&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;counter$&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;interval&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;1000&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;click$&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fromEvent&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;boton&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#34;click&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;counter$&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;takeUntil&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;click$&lt;/span&gt;)).&lt;span style="color:#e06c75"&gt;subscribe&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;next&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;valor&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;next&amp;#34;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;valor&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;complete&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; () &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;complete&amp;#34;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El contador sigue emitiendo cada segundo hasta que el botón produce un evento &lt;code&gt;click&lt;/code&gt;.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/uncommon-operators/console-takeuntil_hu_b86b54f77e79792e.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 






 
 





 


&lt;div class="notice tip"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z" /&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Tip&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;En aplicaciones con componentes, &lt;code&gt;takeUntil&lt;/code&gt; suele conectarse a una señal de destrucción para liberar recursos y cerrar suscripciones de forma predecible.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="skip-omitir-emisiones-iniciales"&gt;&lt;code&gt;skip&lt;/code&gt;: omitir emisiones iniciales&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;skip&lt;/code&gt; ignora las primeras &lt;code&gt;n&lt;/code&gt; emisiones del &lt;code&gt;Observable&lt;/code&gt; fuente y deja pasar las posteriores. Es útil cuando las primeras señales representan inicialización, ruido operativo o eventos que no deben activar la lógica principal.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/uncommon-operators/marble-skip_hu_34ae533aa471be84.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 


&lt;p&gt;Aplicado al ejemplo anterior, podemos exigir varios clics antes de cancelar el contador. Con &lt;code&gt;skip(2)&lt;/code&gt;, el tercer clic es el primero que llega a &lt;code&gt;takeUntil&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;fromEvent&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;interval&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;rxjs&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;skip&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;takeUntil&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;tap&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;rxjs/operators&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;boton&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;document&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;createElement&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;button&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;boton&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;innerHTML&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;Detener timing&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e5c07b"&gt;document&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;querySelector&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;body&amp;#34;&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;?&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;append&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;boton&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;counter$&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;interval&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;1000&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;click$&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;fromEvent&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;boton&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#34;click&amp;#34;&lt;/span&gt;).&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;tap&lt;/span&gt;(() &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;tap-antes&amp;#34;&lt;/span&gt;)),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;skip&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;2&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;tap&lt;/span&gt;(() &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;tap-despues&amp;#34;&lt;/span&gt;)),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;counter$&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;takeUntil&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;click$&lt;/span&gt;)).&lt;span style="color:#e06c75"&gt;subscribe&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;next&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;valor&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;next&amp;#34;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;valor&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;complete&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; () &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;complete&amp;#34;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La salida muestra que los primeros clics existen, pero no cruzan la frontera marcada por &lt;code&gt;skip&lt;/code&gt;.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/uncommon-operators/console-skip_hu_47b321fbdd1deba4.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 


&lt;h2 id="distinct-eliminar-valores-repetidos-globalmente"&gt;&lt;code&gt;distinct&lt;/code&gt;: eliminar valores repetidos globalmente&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;distinct&lt;/code&gt; evita que el flujo emita valores ya observados previamente. La comparación base usa igualdad estricta (&lt;code&gt;===&lt;/code&gt;), por lo que tipo y valor deben coincidir.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/uncommon-operators/marble-distinct_hu_c01e49d9695a2ef6.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 


&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;of&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;rxjs&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;distinct&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;rxjs/operators&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;numeros$&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#c678dd"&gt;of&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;2&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;2&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;4&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;5&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;numeros$&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;distinct&lt;/span&gt;()).&lt;span style="color:#e06c75"&gt;subscribe&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El operador conserva una memoria interna de valores ya emitidos y descarta repeticiones posteriores.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/uncommon-operators/console-distinct_hu_936aafc688e819b5.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 


&lt;h3 id="distinct-con-selector-para-objetos"&gt;&lt;code&gt;distinct&lt;/code&gt; con selector para objetos&lt;/h3&gt;
&lt;p&gt;Con objetos, dos instancias con la misma estructura no son iguales por referencia. Para resolverlo, &lt;code&gt;distinct&lt;/code&gt; acepta un selector que define la clave de comparación.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;rxjs&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;distinct&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;rxjs/operators&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;interface&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Personaje&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;personajes&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;Personaje&lt;/span&gt;[] &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;Megaman&amp;#34;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;Zero&amp;#34;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;X&amp;#34;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;Zero&amp;#34;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;Zero&amp;#34;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;Zero&amp;#34;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;X&amp;#34;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;Megaman&amp;#34;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;Megaman&amp;#34;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;from&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;personajes&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;distinct&lt;/span&gt;((&lt;span style="color:#e06c75"&gt;personaje&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;personaje&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e06c75"&gt;subscribe&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;En este caso la unicidad se calcula por &lt;code&gt;nombre&lt;/code&gt;, no por referencia del objeto.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/uncommon-operators/console-distinct-selector_hu_e2d36d92979adb21.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 






 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;&lt;code&gt;distinct&lt;/code&gt; mantiene un registro de claves ya vistas. En flujos largos o infinitos, evalúa el impacto en memoria o usa una estrategia con cierre explícito.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="distinctuntilchanged-evitar-repeticiones-consecutivas"&gt;&lt;code&gt;distinctUntilChanged&lt;/code&gt;: evitar repeticiones consecutivas&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;distinctUntilChanged&lt;/code&gt; compara cada emisión con la emisión inmediatamente anterior. Solo descarta duplicados consecutivos; si un valor reaparece más adelante después de otro valor distinto, puede emitirse de nuevo.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/uncommon-operators/marble-distinctuntilchanged_hu_910145903f00acd.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 


&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;of&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;rxjs&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;distinctUntilChanged&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;rxjs/operators&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;numeros$&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#c678dd"&gt;of&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#34;1&amp;#34;&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;2&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;2&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;2&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;4&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;5&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;numeros$&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;distinctUntilChanged&lt;/span&gt;()).&lt;span style="color:#e06c75"&gt;subscribe&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La igualdad por defecto también usa &lt;code&gt;===&lt;/code&gt;; por eso &lt;code&gt;1&lt;/code&gt; y &lt;code&gt;&amp;quot;1&amp;quot;&lt;/code&gt; no se consideran duplicados.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/uncommon-operators/console-distinctuntilchanged_hu_c13ce3b955e241eb.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 


&lt;h3 id="distinctuntilchanged-con-comparador"&gt;&lt;code&gt;distinctUntilChanged&lt;/code&gt; con comparador&lt;/h3&gt;
&lt;p&gt;Para objetos, el comparador recibe el valor anterior y el actual. Debe retornar &lt;code&gt;true&lt;/code&gt; cuando ambos se consideran equivalentes y, por tanto, el valor actual debe omitirse.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;rxjs&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;distinctUntilChanged&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;rxjs/operators&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;interface&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Personaje&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;personajes&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;Personaje&lt;/span&gt;[] &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;Megaman&amp;#34;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;Megaman&amp;#34;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;Zero&amp;#34;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;X&amp;#34;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;Zero&amp;#34;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;Zero&amp;#34;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;Zero&amp;#34;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;X&amp;#34;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;Megaman&amp;#34;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;Megaman&amp;#34;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;from&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;personajes&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;distinctUntilChanged&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (&lt;span style="color:#e06c75"&gt;anterior&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;actual&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;anterior&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;===&lt;/span&gt; &lt;span style="color:#e06c75"&gt;actual&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e06c75"&gt;subscribe&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El flujo descarta únicamente los personajes consecutivos con el mismo &lt;code&gt;nombre&lt;/code&gt;.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/uncommon-operators/console-distinctuntilchanged-comparator_hu_f501dff0424ef24d.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 


&lt;h2 id="distinctuntilkeychanged-comparación-consecutiva-por-propiedad"&gt;&lt;code&gt;distinctUntilKeyChanged&lt;/code&gt;: comparación consecutiva por propiedad&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;distinctUntilKeyChanged&lt;/code&gt; aplica la misma idea de &lt;code&gt;distinctUntilChanged&lt;/code&gt;, pero optimizada para objetos cuando la comparación depende de una propiedad concreta.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/uncommon-operators/marble-distinctuntilkeychanged_hu_502038a9e4c7fbd7.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 


&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;rxjs&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;distinctUntilKeyChanged&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;rxjs/operators&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;interface&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Personaje&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;personajes&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;Personaje&lt;/span&gt;[] &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;Megaman&amp;#34;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;Megaman&amp;#34;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;Zero&amp;#34;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;X&amp;#34;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;Zero&amp;#34;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;Zero&amp;#34;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;Zero&amp;#34;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;X&amp;#34;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;Megaman&amp;#34;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;nombre&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;Megaman&amp;#34;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;from&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;personajes&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;distinctUntilKeyChanged&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;nombre&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e06c75"&gt;subscribe&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La intención queda más explícita que con un comparador manual cuando solo necesitas evaluar una clave.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/uncommon-operators/console-distinctuntilkeychanged_hu_a313d9c96362d79c.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 


&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;Estos operadores no son secundarios; resuelven decisiones críticas de ciclo de vida, cancelación y deduplicación en flujos reactivos. &lt;code&gt;take&lt;/code&gt;, &lt;code&gt;first&lt;/code&gt;, &lt;code&gt;takeWhile&lt;/code&gt;, &lt;code&gt;takeUntil&lt;/code&gt; y &lt;code&gt;skip&lt;/code&gt; controlan cuántas emisiones llegan al consumidor y cuándo termina la suscripción. &lt;code&gt;distinct&lt;/code&gt;, &lt;code&gt;distinctUntilChanged&lt;/code&gt; y &lt;code&gt;distinctUntilKeyChanged&lt;/code&gt; controlan repetición y semántica de igualdad.&lt;/p&gt;
&lt;p&gt;La regla práctica es seleccionar el operador según el límite que necesitas expresar: cantidad, condición, señal externa, emisiones iniciales o duplicados. Esa precisión mantiene tus pipelines de RxJS más declarativos, auditables y fáciles de mantener.&lt;/p&gt;</content:encoded></item><item><title>Estilos CSS: Dominando el modelo de caja</title><link>https://blog.dacadev.com/programacion/estilos-css/modelo-de-caja/</link><pubDate>Sat, 06 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/programacion/estilos-css/modelo-de-caja/</guid><dc:creator>Dacadev</dc:creator><category>programación</category><description>Domina el modelo de caja en CSS: content-box vs border-box, control de overflow, alturas orgánicas, centrado vertical, márgenes negativos y colapso de márgenes.</description><media:content url="https://blog.dacadev.com/images/programming/html-and-css/css/03-modelo-de-caja-banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#las-cuatro-regiones-de-una-caja"&gt;Las cuatro regiones de una caja&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#box-sizing-content-box-vs-border-box"&gt;&lt;code&gt;box-sizing&lt;/code&gt;: content-box vs border-box&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#alturas-el-flujo-normal-manda"&gt;Alturas: el flujo normal manda&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#overflow-qué-hacer-cuando-el-contenido-se-desborda"&gt;&lt;code&gt;overflow&lt;/code&gt;: qué hacer cuando el contenido se desborda&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#centrado-vertical"&gt;Centrado vertical&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#márgenes-negativos"&gt;Márgenes negativos&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#colapso-de-márgenes-margin-collapsing"&gt;Colapso de márgenes (margin collapsing)&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#conclusión"&gt;Conclusión&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;p&gt;El modelo de caja es el sistema con el que CSS calcula el tamaño y el espaciado de cada elemento. Parece trivial, pero es la fuente número uno de layouts impredecibles: un &lt;code&gt;width: 50%&lt;/code&gt; que termina midiendo más de la mitad, dos columnas que no encajan, márgenes que desaparecen sin razón aparente. Todos esos síntomas se explican entendiendo cómo el navegador compone una caja.&lt;/p&gt;
&lt;p&gt;Esta es la tercera entrega de la serie &lt;strong&gt;Estilos CSS&lt;/strong&gt;. Analizaremos las cuatro regiones de una caja, el cambio de comportamiento que introduce &lt;code&gt;box-sizing&lt;/code&gt;, el control de &lt;code&gt;overflow&lt;/code&gt;, el manejo de alturas, el centrado vertical y el colapso de márgenes.&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Comprenderás por qué &lt;code&gt;box-sizing: border-box&lt;/code&gt; debería ser tu valor por defecto y aprenderás a resolver los problemas clásicos de altura, centrado vertical y colapso de márgenes.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="las-cuatro-regiones-de-una-caja"&gt;Las cuatro regiones de una caja&lt;/h2&gt;
&lt;p&gt;Todo elemento HTML se compone, de adentro hacia afuera, de cuatro capas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;content&lt;/strong&gt; — el área donde vive el contenido (texto, imágenes).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;padding&lt;/strong&gt; — el espacio interno entre el contenido y el borde.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;border&lt;/strong&gt; — el borde que rodea el padding.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;margin&lt;/strong&gt; — el espacio externo que separa la caja de sus vecinos.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;div&lt;/span&gt; &lt;span style="color:#e06c75"&gt;class&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#34;caja&amp;#34;&lt;/span&gt;&amp;gt;content + padding + border + margin&amp;lt;/&lt;span style="color:#e06c75"&gt;div&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border:1px dashed #f39c12;border-radius:.5rem;padding:1rem;background:#fff;color:#111;margin:1rem 0;"&gt;
 &lt;div style="background:#fdebd0;padding:1.25rem;border:3px solid #2a9da9;font-family:Helvetica,Arial,sans-serif;color:#111;"&gt;
 &lt;div style="background:#aed6f1;padding:.75rem;"&gt;content&lt;/div&gt;
 &lt;small style="display:block;margin-top:.4rem;color:#555;"&gt;El área azul es el &lt;code&gt;content&lt;/code&gt;; el beige es el &lt;code&gt;padding&lt;/code&gt;; el trazo turquesa es el &lt;code&gt;border&lt;/code&gt;; el espacio punteado exterior es el &lt;code&gt;margin&lt;/code&gt;.&lt;/small&gt;
 &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="box-sizing-content-box-vs-border-box"&gt;&lt;code&gt;box-sizing&lt;/code&gt;: content-box vs border-box&lt;/h2&gt;
&lt;p&gt;La propiedad &lt;code&gt;box-sizing&lt;/code&gt; decide qué incluye el &lt;code&gt;width&lt;/code&gt; y el &lt;code&gt;height&lt;/code&gt; que declaras.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;content-box&lt;/code&gt;&lt;/strong&gt; (valor por defecto) — &lt;code&gt;width&lt;/code&gt; y &lt;code&gt;height&lt;/code&gt; miden &lt;strong&gt;solo&lt;/strong&gt; el contenido. El &lt;code&gt;padding&lt;/code&gt; y el &lt;code&gt;border&lt;/code&gt; se suman &lt;em&gt;por fuera&lt;/em&gt;, agrandando el tamaño final.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;border-box&lt;/code&gt;&lt;/strong&gt; — &lt;code&gt;width&lt;/code&gt; y &lt;code&gt;height&lt;/code&gt; miden el conjunto de contenido + padding + border. El tamaño que declaras es el tamaño real renderizado.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Mira dos cajas con &lt;code&gt;width: 200px&lt;/code&gt; y &lt;code&gt;padding: 20px&lt;/code&gt;, una con cada modelo:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;content-box&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;box-sizing&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;content-box&lt;/span&gt;; } &lt;span style="color:#7f848e"&gt;/* ancho real: 200 + 40 = 240px */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;border-box&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;box-sizing&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;border-box&lt;/span&gt;; } &lt;span style="color:#7f848e"&gt;/* ancho real: 200px */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border:1px solid #d0d0d0;border-radius:.5rem;padding:1rem;background:#fff;color:#111;margin:1rem 0;font-family:Helvetica,Arial,sans-serif;"&gt;
 &lt;div style="box-sizing:content-box;width:200px;padding:20px;border:3px solid #c0392b;background:#fdecea;margin-bottom:.75rem;color:#111;"&gt;content-box → mide 246px en total&lt;/div&gt;
 &lt;div style="box-sizing:border-box;width:200px;padding:20px;border:3px solid #27ae60;background:#eafaf1;color:#111;"&gt;border-box → mide 200px en total&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Por eso es práctica recomendada activar &lt;code&gt;border-box&lt;/code&gt; de forma global, heredándolo para no romper estilos de terceros:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;:&lt;span style="color:#61afef"&gt;root&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;box-sizing&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;border-box&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#56b6c2"&gt;*,&lt;/span&gt; ::&lt;span style="color:#61afef"&gt;before&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;,&lt;/span&gt; ::&lt;span style="color:#61afef"&gt;after&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;box-sizing&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;inherit&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Evita los &lt;strong&gt;números mágicos&lt;/strong&gt;: valores arbitrarios (&lt;code&gt;margin-top: 37px&lt;/code&gt;) que &amp;ldquo;cuadran&amp;rdquo; un diseño por casualidad. Haz que el contenido se adapte al contenedor, no al revés.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="alturas-el-flujo-normal-manda"&gt;Alturas: el flujo normal manda&lt;/h2&gt;
&lt;p&gt;La altura de un contenedor es &lt;strong&gt;orgánica&lt;/strong&gt; por defecto: la define su contenido, no el contenedor. Esto tiene dos consecuencias prácticas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Definir &lt;code&gt;height&lt;/code&gt; en porcentaje rara vez funciona, porque se refiere a la altura del padre, que a su vez depende de su contenido.&lt;/li&gt;
&lt;li&gt;Para que un &lt;code&gt;height: 100%&lt;/code&gt; funcione, el padre necesita una altura explícita en unidades absolutas.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;En lugar de fijar alturas, prefiere restringir el rango con &lt;code&gt;min-height&lt;/code&gt; y &lt;code&gt;max-height&lt;/code&gt;, dejando que el contenido fluya:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;panel&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;min-height&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;6&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;em&lt;/span&gt;; &lt;span style="color:#c678dd"&gt;max-height&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;12&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;em&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="overflow-qué-hacer-cuando-el-contenido-se-desborda"&gt;&lt;code&gt;overflow&lt;/code&gt;: qué hacer cuando el contenido se desborda&lt;/h2&gt;
&lt;p&gt;Cuando el contenido excede el tamaño de su caja, &lt;code&gt;overflow&lt;/code&gt; define el comportamiento:&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Valor&lt;/th&gt;
 &lt;th&gt;Comportamiento&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;visible&lt;/code&gt; (por defecto)&lt;/td&gt;
 &lt;td&gt;El contenido se desborda y permanece visible.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;hidden&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;El contenido que se sale se recorta.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;scroll&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Siempre añade barras de desplazamiento.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;auto&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Añade barras solo si hace falta.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;recorte&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;overflow&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;auto&lt;/span&gt;; &lt;span style="color:#c678dd"&gt;max-height&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;5&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;em&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border:1px solid #d0d0d0;border-radius:.5rem;padding:1rem;background:#fff;color:#111;margin:1rem 0;font-family:Helvetica,Arial,sans-serif;"&gt;
 &lt;div style="overflow:auto;max-height:5em;border:1px solid #ccc;padding:.5rem;color:#111;"&gt;
 &lt;p style="margin:0 0 .5rem;"&gt;Este contenedor tiene &lt;code&gt;overflow: auto&lt;/code&gt; y una altura máxima.&lt;/p&gt;
 &lt;p style="margin:0 0 .5rem;"&gt;Cuando el contenido supera esa altura, aparece una barra de desplazamiento.&lt;/p&gt;
 &lt;p style="margin:0 0 .5rem;"&gt;Línea adicional para forzar el desbordamiento.&lt;/p&gt;
 &lt;p style="margin:0;"&gt;Y una más para asegurar el scroll.&lt;/p&gt;
 &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Puedes controlar cada eje por separado con &lt;code&gt;overflow-x&lt;/code&gt; y &lt;code&gt;overflow-y&lt;/code&gt;, aunque mezclar valores distintos suele dar resultados poco predecibles.&lt;/p&gt;
&lt;h2 id="centrado-vertical"&gt;Centrado vertical&lt;/h2&gt;
&lt;p&gt;Centrar verticalmente fue durante años un dolor de cabeza en CSS. La propiedad &lt;code&gt;vertical-align&lt;/code&gt; no sirve para esto: solo aplica a elementos &lt;code&gt;inline&lt;/code&gt; y a celdas de tabla. Hoy tenemos varias soluciones según el escenario:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;¿Puedes usar la altura natural?&lt;/strong&gt; Aplica un &lt;code&gt;padding&lt;/code&gt; igual arriba y abajo.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;¿Necesitas altura fija?&lt;/strong&gt; Usa &lt;code&gt;display: table-cell&lt;/code&gt; con &lt;code&gt;vertical-align: middle&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;El caso general:&lt;/strong&gt; usa &lt;strong&gt;flexbox&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;¿Una sola línea de texto?&lt;/strong&gt; Usa &lt;code&gt;line-height&lt;/code&gt; igual a la altura del contenedor.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;La solución moderna por excelencia es flexbox, que centra en ambos ejes con tres declaraciones:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;centro&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;display&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;flex&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;align-items&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;center&lt;/span&gt;; &lt;span style="color:#7f848e"&gt;/* eje vertical */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;justify-content&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;center&lt;/span&gt;; &lt;span style="color:#7f848e"&gt;/* eje horizontal */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;min-height&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;8&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;em&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border:1px solid #d0d0d0;border-radius:.5rem;padding:1rem;background:#fff;color:#111;margin:1rem 0;"&gt;
 &lt;div style="display:flex;align-items:center;justify-content:center;min-height:8em;background:#eaf2f8;border-radius:.4em;font-family:Helvetica,Arial,sans-serif;"&gt;
 &lt;span style="background:#2a9da9;color:#fff;padding:.6em 1.2em;border-radius:.4em;"&gt;Centrado en ambos ejes&lt;/span&gt;
 &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="márgenes-negativos"&gt;Márgenes negativos&lt;/h2&gt;
&lt;p&gt;A diferencia de &lt;code&gt;padding&lt;/code&gt; y &lt;code&gt;border&lt;/code&gt;, los márgenes admiten valores &lt;strong&gt;negativos&lt;/strong&gt;, lo que te permite tirar de un elemento hacia afuera de su posición natural o solaparlo con su vecino.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#e5c07b"&gt;solapado&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;margin-top&lt;/span&gt;: &lt;span style="color:#d19a66"&gt;-1.5&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;em&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="border:1px solid #d0d0d0;border-radius:.5rem;padding:1rem;background:#fff;color:#111;margin:1rem 0;font-family:Helvetica,Arial,sans-serif;"&gt;
 &lt;div style="background:#2a9da9;color:#fff;padding:1em;border-radius:.4em;"&gt;Bloque base&lt;/div&gt;
 &lt;div style="background:#f39c12;color:#fff;padding:1em;border-radius:.4em;margin-top:-1.5em;margin-left:2em;"&gt;Bloque con &lt;code&gt;margin-top&lt;/code&gt; negativo que se solapa&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="colapso-de-márgenes-margin-collapsing"&gt;Colapso de márgenes (margin collapsing)&lt;/h2&gt;
&lt;p&gt;Cuando dos márgenes verticales se encuentran, &lt;strong&gt;no se suman&lt;/strong&gt;: se &lt;em&gt;colapsan&lt;/em&gt;, quedando solo el de mayor valor. Si un párrafo tiene &lt;code&gt;margin-bottom: 30px&lt;/code&gt; y el siguiente &lt;code&gt;margin-top: 20px&lt;/code&gt;, la separación entre ambos será de &lt;code&gt;30px&lt;/code&gt;, no &lt;code&gt;50px&lt;/code&gt;.&lt;/p&gt;




 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;El colapso de márgenes solo ocurre con márgenes &lt;strong&gt;verticales&lt;/strong&gt; (arriba y abajo). Los márgenes horizontales (izquierda y derecha) nunca colapsan.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Hay varias formas de impedir el colapso cuando no lo deseas:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Aplicar &lt;code&gt;overflow: auto&lt;/code&gt; (o cualquier valor distinto de &lt;code&gt;visible&lt;/code&gt;) al contenedor.&lt;/li&gt;
&lt;li&gt;Añadir un &lt;code&gt;border&lt;/code&gt; o un &lt;code&gt;padding&lt;/code&gt; entre los dos márgenes.&lt;/li&gt;
&lt;li&gt;Usar un contenedor flotado, &lt;code&gt;inline-block&lt;/code&gt; o con posición absoluta/fija.&lt;/li&gt;
&lt;li&gt;Usar &lt;strong&gt;flexbox&lt;/strong&gt; o &lt;strong&gt;grid&lt;/strong&gt;: los márgenes entre ítems del layout no colapsan.&lt;/li&gt;
&lt;li&gt;Los elementos con &lt;code&gt;display: table-cell&lt;/code&gt; no tienen margen, así que no colapsan.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;El modelo de caja deja de ser un misterio cuando interiorizas que &lt;code&gt;box-sizing&lt;/code&gt; controla la aritmética del tamaño, que la altura es orgánica por naturaleza y que los márgenes verticales colapsan. Activar &lt;code&gt;border-box&lt;/code&gt; de forma global y apoyarte en flexbox para el centrado elimina la mayoría de los problemas clásicos de maquetación.&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;🚀 La siguiente entrega cubre los sistemas de &lt;strong&gt;layout&lt;/strong&gt;: &lt;code&gt;float&lt;/code&gt;, &lt;strong&gt;flexbox&lt;/strong&gt; y &lt;strong&gt;CSS Grid&lt;/strong&gt;, las herramientas con las que componemos la estructura completa de una página.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
</content:encoded></item><item><title>RxJs: Operadores de transformación</title><link>https://blog.dacadev.com/typescript/rxjs/operadores-de-transformacion-rxjs/</link><pubDate>Fri, 05 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/typescript/rxjs/operadores-de-transformacion-rxjs/</guid><dc:creator>Dacadev</dc:creator><category>programación</category><description>Aprende operadores de transformación RxJS para aplanar flujos con mergeAll, mergeMap, switchMap, concatMap y exhaustMap.</description><media:content url="https://blog.dacadev.com/images/typescript/rxjs/transformation-operators/banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#mergeall-aplanar-observables-internos-con-concurrencia"&gt;&lt;code&gt;mergeAll&lt;/code&gt;: aplanar observables internos con concurrencia&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#mergemap-transformar-y-mezclar-con-concurrencia-completa"&gt;&lt;code&gt;mergeMap&lt;/code&gt;: transformar y mezclar con concurrencia completa&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#switchmap-cancelar-lo-anterior-y-conservar-lo-más-reciente"&gt;&lt;code&gt;switchMap&lt;/code&gt;: cancelar lo anterior y conservar lo más reciente&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#concatmap-preservar-orden-y-ejecutar-de-forma-secuencial"&gt;&lt;code&gt;concatMap&lt;/code&gt;: preservar orden y ejecutar de forma secuencial&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#exhaustmap-ignorar-nuevas-emisiones-mientras-hay-trabajo-activo"&gt;&lt;code&gt;exhaustMap&lt;/code&gt;: ignorar nuevas emisiones mientras hay trabajo activo&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#cuándo-elegir-cada-operador-de-transformación-rxjs"&gt;Cuándo elegir cada operador de transformación RxJS&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#conclusión"&gt;Conclusión&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;p&gt;Cuando una aplicación combina eventos de UI, peticiones HTTP y procesos asíncronos, el flujo deja de ser una secuencia plana de valores y empieza a producir &lt;strong&gt;observables internos&lt;/strong&gt;. Los &lt;strong&gt;operadores de transformación RxJS&lt;/strong&gt; resuelven ese punto crítico: convierten un observable de observables en un flujo consumible, controlando concurrencia, cancelación, orden y exclusión de trabajo duplicado.&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Este artículo forma parte de la &lt;strong&gt;serie RxJs&lt;/strong&gt;. Venimos de analizar &lt;a href="https://blog.dacadev.com/typescript/operadores-de-tiempo-rxjs/"



 


&gt;Operadores de tiempo&lt;/a&gt; y aquí abordaremos &lt;code&gt;mergeAll&lt;/code&gt;, &lt;code&gt;mergeMap&lt;/code&gt;, &lt;code&gt;switchMap&lt;/code&gt;, &lt;code&gt;concatMap&lt;/code&gt; y &lt;code&gt;exhaustMap&lt;/code&gt;; después continuaremos con &lt;a href="https://blog.dacadev.com/typescript/operadores-no-tan-comunes-rxjs/"



 


&gt;Operadores no tan comunes&lt;/a&gt;.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;La documentación oficial de &lt;a href="https://rxjs.dev"




 target="_blank"
 


&gt;RxJS&lt;/a&gt; describe estos operadores como herramientas para trabajar con &lt;strong&gt;higher-order observables&lt;/strong&gt;: observables cuyas emisiones son, a su vez, otros observables. En términos prácticos, aparecen cada vez que un evento dispara trabajo asíncrono: una búsqueda, un guardado, una carga incremental o una operación remota.&lt;/p&gt;
&lt;p&gt;La diferencia entre estos operadores no es cosmética. Elegir uno u otro define cómo se comporta el sistema ante emisiones rápidas: si ejecuta todo en paralelo, cancela lo anterior, serializa las tareas o ignora nuevos eventos mientras una operación sigue activa.&lt;/p&gt;
&lt;h2 id="mergeall-aplanar-observables-internos-con-concurrencia"&gt;&lt;code&gt;mergeAll&lt;/code&gt;: aplanar observables internos con concurrencia&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;mergeAll&lt;/code&gt; trabaja sobre un observable que emite observables. Se suscribe a cada observable interno y reemite sus valores en el flujo resultante. El resultado se completa únicamente cuando el observable exterior se completa y todos los observables internos activos también han completado.&lt;/p&gt;
&lt;p&gt;Este operador es útil cuando ya tienes construidos los observables internos y solo necesitas aplanarlos. Por ejemplo, una capa previa puede generar varias operaciones independientes: guardar un borrador, registrar auditoría y sincronizar métricas. Si ninguna depende del resultado de la otra, &lt;code&gt;mergeAll&lt;/code&gt; permite ejecutarlas con concurrencia.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/transformation-operators/marble-mergeall_hu_994d656b4b603393.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 


&lt;p&gt;En el diagrama, cada emisión del flujo superior representa un observable interno. &lt;code&gt;mergeAll&lt;/code&gt; mezcla sus emisiones conforme llegan, sin preservar necesariamente el orden original entre observables.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;from&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;mapTo&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;mergeAll&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;timer&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;saveDraft$&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;timer&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;300&lt;/span&gt;).&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;mapTo&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;draft saved&amp;#39;&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sendAudit$&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;timer&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;100&lt;/span&gt;).&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;mapTo&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;audit sent&amp;#39;&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;syncMetrics$&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;timer&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;200&lt;/span&gt;).&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;mapTo&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;metrics synced&amp;#39;&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;from&lt;/span&gt;([&lt;span style="color:#e06c75"&gt;saveDraft$&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;sendAudit$&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;syncMetrics$&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;mergeAll&lt;/span&gt;())
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e06c75"&gt;subscribe&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// audit sent
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// metrics synced
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;// draft saved
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El ejemplo muestra un comportamiento clave: el orden de salida depende del tiempo de finalización de cada observable interno. Si necesitas preservar orden estricto, &lt;code&gt;mergeAll&lt;/code&gt; no es la herramienta adecuada; &lt;code&gt;concatMap&lt;/code&gt; encaja mejor en ese caso.&lt;/p&gt;




 
 





 


&lt;div class="notice tip"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z" /&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Tip&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Usa &lt;code&gt;mergeAll&lt;/code&gt; cuando ya tienes observables internos construidos y deseas aplanarlos. Si primero necesitas transformar cada valor del flujo exterior en un observable, normalmente &lt;code&gt;mergeMap&lt;/code&gt; expresa mejor la intención.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="mergemap-transformar-y-mezclar-con-concurrencia-completa"&gt;&lt;code&gt;mergeMap&lt;/code&gt;: transformar y mezclar con concurrencia completa&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;mergeMap&lt;/code&gt; combina dos pasos: transforma cada emisión del observable fuente en un observable interno y luego mezcla las emisiones de todos esos observables. Conceptualmente equivale a aplicar &lt;code&gt;map&lt;/code&gt; para crear observables y después &lt;code&gt;mergeAll&lt;/code&gt; para aplanarlos.&lt;/p&gt;
&lt;p&gt;Su semántica favorece la concurrencia. Cada emisión entrante dispara una nueva suscripción interna, y las suscripciones anteriores permanecen activas hasta completar. Esto lo hace adecuado para operaciones independientes donde cancelar trabajo previo sería incorrecto, como escrituras, telemetría, cargas paralelas o procesamiento de elementos sin dependencia de orden.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/transformation-operators/marble-mergemap_hu_8f747c544c480b92.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 


&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#c678dd"&gt;from&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;mergeMap&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;ajax&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs/ajax&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;interface&lt;/span&gt; &lt;span style="color:#e06c75"&gt;User&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;id&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;number&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;userIds&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; [&lt;span style="color:#d19a66"&gt;101&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;102&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;103&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;104&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;from&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;userIds&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;mergeMap&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (&lt;span style="color:#e06c75"&gt;id&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ajax&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;getJSON&lt;/span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;User&lt;/span&gt;&amp;gt;(&lt;span style="color:#98c379"&gt;`/api/users/&lt;/span&gt;&lt;span style="color:#98c379"&gt;${&lt;/span&gt;&lt;span style="color:#e06c75"&gt;id&lt;/span&gt;&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt;`&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#d19a66"&gt;4&lt;/span&gt; &lt;span style="color:#7f848e"&gt;// límite de concurrencia
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e06c75"&gt;subscribe&lt;/span&gt;((&lt;span style="color:#e06c75"&gt;user&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;Usuario cargado:&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;user&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;name&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Aunque &lt;code&gt;mergeMap&lt;/code&gt; suele asociarse con “concurrencia completa”, RxJS permite limitar esa concurrencia con el segundo argumento. Este detalle es importante cuando el flujo fuente puede emitir muchos valores y cada valor dispara trabajo costoso, como peticiones HTTP o acceso a recursos externos.&lt;/p&gt;




 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;&lt;code&gt;mergeMap&lt;/code&gt; no cancela observables internos anteriores. Si el flujo fuente emite más rápido de lo que los internos completan, puedes acumular trabajo concurrente y aumentar presión sobre red, memoria o servicios remotos.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="switchmap-cancelar-lo-anterior-y-conservar-lo-más-reciente"&gt;&lt;code&gt;switchMap&lt;/code&gt;: cancelar lo anterior y conservar lo más reciente&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;switchMap&lt;/code&gt; también transforma cada emisión en un observable interno, pero mantiene activa solo la suscripción más reciente. Cuando llega una nueva emisión desde el observable fuente, cancela la suscripción interna anterior y se cambia al nuevo observable.&lt;/p&gt;
&lt;p&gt;Esta semántica es ideal para escenarios donde el resultado anterior pierde relevancia al aparecer una entrada más nueva. El caso clásico es un typeahead o autocomplete: si el usuario escribe &lt;code&gt;rea&lt;/code&gt; y luego &lt;code&gt;react&lt;/code&gt;, la respuesta de &lt;code&gt;rea&lt;/code&gt; ya no debe actualizar la UI aunque llegue después.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/transformation-operators/marble-switchmap_hu_113998a3529e5491.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 


&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;debounceTime&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;distinctUntilChanged&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;fromEvent&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;map&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;of&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;switchMap&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;} &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;ajax&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs/ajax&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;interface&lt;/span&gt; &lt;span style="color:#e06c75"&gt;SearchResult&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;id&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;title&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;input&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;document&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;querySelector&lt;/span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;HTMLInputElement&lt;/span&gt;&amp;gt;(&lt;span style="color:#98c379"&gt;&amp;#39;#search&amp;#39;&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;!&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;fromEvent&lt;/span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;InputEvent&lt;/span&gt;&amp;gt;(&lt;span style="color:#e06c75"&gt;input&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;input&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;map&lt;/span&gt;((&lt;span style="color:#e06c75"&gt;event&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; (&lt;span style="color:#e06c75"&gt;event&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;target&lt;/span&gt; &lt;span style="color:#c678dd"&gt;as&lt;/span&gt; &lt;span style="color:#e06c75"&gt;HTMLInputElement&lt;/span&gt;).&lt;span style="color:#e06c75"&gt;value&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;trim&lt;/span&gt;()),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;debounceTime&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;300&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;distinctUntilChanged&lt;/span&gt;(),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;switchMap&lt;/span&gt;((&lt;span style="color:#e06c75"&gt;term&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;term&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;length&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;===&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;?&lt;/span&gt; &lt;span style="color:#c678dd"&gt;of&lt;/span&gt;([])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ajax&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;getJSON&lt;/span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;SearchResult&lt;/span&gt;[]&amp;gt;(&lt;span style="color:#98c379"&gt;`/api/search?q=&lt;/span&gt;&lt;span style="color:#98c379"&gt;${&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;encodeURIComponent&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;term&lt;/span&gt;)&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt;`&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e06c75"&gt;subscribe&lt;/span&gt;((&lt;span style="color:#e06c75"&gt;results&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;Resultados vigentes:&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;results&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El valor operativo de &lt;code&gt;switchMap&lt;/code&gt; está en la cancelación. En Angular, por ejemplo, cancelar la suscripción a una petición HTTP puede abortar la solicitud subyacente; en otros contextos, al menos evita que respuestas obsoletas lleguen al consumidor final.&lt;/p&gt;




 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Elige &lt;code&gt;switchMap&lt;/code&gt; cuando el sistema debe representar el estado más reciente: búsquedas, filtros dinámicos, navegación dependiente de parámetros o recarga de datos por selección activa.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="concatmap-preservar-orden-y-ejecutar-de-forma-secuencial"&gt;&lt;code&gt;concatMap&lt;/code&gt;: preservar orden y ejecutar de forma secuencial&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;concatMap&lt;/code&gt; transforma cada emisión en un observable interno, pero no se suscribe al siguiente hasta que el observable interno actual completa. En lugar de mezclar resultados, crea una cola: procesa una tarea, espera su finalización y continúa con la siguiente.&lt;/p&gt;
&lt;p&gt;Este comportamiento es crucial cuando el orden importa o cuando el backend espera operaciones serializadas. Casos típicos incluyen guardar cambios en secuencia, ejecutar comandos de dominio, procesar pasos de onboarding o enviar eventos que deben respetar causalidad.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/transformation-operators/marble-concatmap_hu_6f93690790aa1f0e.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 


&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;concatMap&lt;/span&gt;, &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;ajax&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs/ajax&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;interface&lt;/span&gt; &lt;span style="color:#e06c75"&gt;OrderCommand&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;orderId&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;status&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;validated&amp;#39;&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;charged&amp;#39;&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;confirmed&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;commands&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;OrderCommand&lt;/span&gt;[] &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;orderId&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;A-100&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;status&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;validated&amp;#39;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;orderId&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;A-100&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;status&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;charged&amp;#39;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e06c75"&gt;orderId&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;A-100&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;status&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;confirmed&amp;#39;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;from&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;commands&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;concatMap&lt;/span&gt;((&lt;span style="color:#e06c75"&gt;command&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;ajax&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;post&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;/api/orders/commands&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;command&lt;/span&gt;, {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Content-Type&amp;#39;&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;application/json&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e06c75"&gt;subscribe&lt;/span&gt;(() &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;Comando procesado en orden&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La principal ventaja de &lt;code&gt;concatMap&lt;/code&gt; es la predictibilidad. La desventaja es la latencia acumulada: si cada operación tarda 500 ms y tienes diez elementos, el flujo tardará al menos cinco segundos en procesar la cola completa.&lt;/p&gt;




 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;&lt;code&gt;concatMap&lt;/code&gt; puede acumular una cola grande si la fuente emite más rápido de lo que completan los observables internos. Evalúa backpressure, límites de entrada o estrategias de descarte si el volumen no está controlado.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="exhaustmap-ignorar-nuevas-emisiones-mientras-hay-trabajo-activo"&gt;&lt;code&gt;exhaustMap&lt;/code&gt;: ignorar nuevas emisiones mientras hay trabajo activo&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;exhaustMap&lt;/code&gt; transforma una emisión en un observable interno y, mientras ese observable está activo, ignora todas las emisiones posteriores del observable fuente. Cuando el observable interno completa, el operador queda listo para aceptar una nueva emisión.&lt;/p&gt;
&lt;p&gt;Este patrón es útil cuando una operación no debe ejecutarse dos veces en paralelo. Formularios de login, botones de pago, acciones de envío y procesos idempotentes costosos suelen beneficiarse de esta semántica: el primer evento inicia el trabajo y los siguientes clics se descartan hasta terminar.&lt;/p&gt;




 
 
 
 &lt;div class="flex justify-center"&gt;
 &lt;img
 src="https://blog.dacadev.com/images/typescript/rxjs/transformation-operators/marble-exhaustmap_hu_b8ae1a19035b9470.webp"
 alt="Imagen guia del contenido de la página"style="width:600px"/&gt;
 &lt;/div&gt;
 
 
 


&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;exhaustMap&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;fromEvent&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;ajax&lt;/span&gt; } &lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;rxjs/ajax&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;interface&lt;/span&gt; &lt;span style="color:#e06c75"&gt;PaymentResult&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;transactionId&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;payButton&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;document&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;querySelector&lt;/span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;HTMLButtonElement&lt;/span&gt;&amp;gt;(&lt;span style="color:#98c379"&gt;&amp;#39;#pay&amp;#39;&lt;/span&gt;)&lt;span style="color:#56b6c2"&gt;!&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;const&lt;/span&gt; &lt;span style="color:#e06c75"&gt;payload&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; { &lt;span style="color:#e06c75"&gt;orderId&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;A-100&amp;#39;&lt;/span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;fromEvent&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;payButton&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;click&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e06c75"&gt;pipe&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;exhaustMap&lt;/span&gt;(() &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;ajax&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;post&lt;/span&gt;&amp;lt;&lt;span style="color:#e06c75"&gt;PaymentResult&lt;/span&gt;&amp;gt;(&lt;span style="color:#98c379"&gt;&amp;#39;/api/payments&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;payload&lt;/span&gt;, {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;Content-Type&amp;#39;&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;:&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;application/json&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#e06c75"&gt;subscribe&lt;/span&gt;((&lt;span style="color:#e06c75"&gt;response&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;=&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;console&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;log&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;Pago procesado:&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;response&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;response&lt;/span&gt;.&lt;span style="color:#e06c75"&gt;transactionId&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A diferencia de &lt;code&gt;switchMap&lt;/code&gt;, &lt;code&gt;exhaustMap&lt;/code&gt; no cancela el trabajo activo. A diferencia de &lt;code&gt;mergeMap&lt;/code&gt;, tampoco crea trabajo adicional. Su contrato es deliberadamente estricto: “ignorar mientras esté ocupado”.&lt;/p&gt;
&lt;h2 id="cuándo-elegir-cada-operador-de-transformación-rxjs"&gt;Cuándo elegir cada operador de transformación RxJS&lt;/h2&gt;
&lt;p&gt;La elección correcta depende de la política de concurrencia que necesita el sistema, no solo de la forma del código.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Usa &lt;code&gt;mergeAll&lt;/code&gt; cuando recibes observables internos ya creados y quieres mezclarlos.&lt;/li&gt;
&lt;li&gt;Usa &lt;code&gt;mergeMap&lt;/code&gt; cuando cada emisión dispara trabajo independiente y aceptas concurrencia.&lt;/li&gt;
&lt;li&gt;Usa &lt;code&gt;switchMap&lt;/code&gt; cuando solo importa el resultado más reciente y conviene cancelar lo anterior.&lt;/li&gt;
&lt;li&gt;Usa &lt;code&gt;concatMap&lt;/code&gt; cuando necesitas orden, serialización o consistencia secuencial.&lt;/li&gt;
&lt;li&gt;Usa &lt;code&gt;exhaustMap&lt;/code&gt; cuando una operación activa debe bloquear nuevas emisiones hasta completar.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Una regla práctica es observar qué debería ocurrir si llegan tres emisiones rápidas. Si las tres deben ejecutarse, &lt;code&gt;mergeMap&lt;/code&gt;. Si solo la última importa, &lt;code&gt;switchMap&lt;/code&gt;. Si las tres deben ejecutarse en orden, &lt;code&gt;concatMap&lt;/code&gt;. Si solo la primera debe ejecutarse y las demás deben ignorarse mientras está activa, &lt;code&gt;exhaustMap&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;Los operadores de transformación RxJS definen cómo se conectan eventos de alto nivel con trabajo asíncrono real. &lt;code&gt;mergeAll&lt;/code&gt;, &lt;code&gt;mergeMap&lt;/code&gt;, &lt;code&gt;switchMap&lt;/code&gt;, &lt;code&gt;concatMap&lt;/code&gt; y &lt;code&gt;exhaustMap&lt;/code&gt; no son variantes intercambiables; cada uno codifica una política distinta de concurrencia, cancelación y orden.&lt;/p&gt;
&lt;p&gt;Al diseñar flujos reactivos en TypeScript, conviene elegir el operador a partir del contrato del dominio. Esa decisión reduce condiciones de carrera, evita respuestas obsoletas, controla presión sobre recursos externos y hace que la intención del flujo sea explícita para el equipo.&lt;/p&gt;</content:encoded></item></channel></rss>