<?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>Typescript · DacaCode &lt;/&gt;</title><link>https://blog.dacadev.com/series/typescript/</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>Wed, 24 Jun 2026 00:00:00 -0500</lastBuildDate><atom:link href="https://blog.dacadev.com/series/typescript/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>TypeScript: Depuración de errores y tsconfig.json</title><link>https://blog.dacadev.com/programacion/typescript/depuracion-y-tsconfig/</link><pubDate>Wed, 24 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/programacion/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/programming/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] --&gt; B[tsc con strict]
 B -- error de tipo --&gt; C[Mensaje TSxxxx&lt;br/&gt;en compilación]
 B -- ok --&gt; D[JS + sourceMap]
 D --&gt; E[Runtime]
 E -- error --&gt; F[Stack trace sobre TS&lt;br/&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>TypeScript: Namespaces, módulos e importaciones</title><link>https://blog.dacadev.com/programacion/typescript/namespaces-y-modulos/</link><pubDate>Tue, 23 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/programacion/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/programming/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] --&gt; I[index.ts barrel]
 V[villain.ts] --&gt; I
 I --&gt; C[consumidor: import desde './interfaces']
&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/programacion/typescript/decoradores/</link><pubDate>Mon, 22 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/programacion/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/programming/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/programacion/typescript/tipos-avanzados/</link><pubDate>Sun, 21 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/programacion/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/programming/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] --&gt; Any[any]
 Any --&gt; Number
 Any --&gt; BigInt
 Any --&gt; Boolean
 Any --&gt; String
 Any --&gt; Symbol
 Any --&gt; Object
 Any --&gt; Void
 Any --&gt; Null
 Any --&gt; Undefined
 Object --&gt; Array
 Array --&gt; Tuple
 Object --&gt; Function
 Number --&gt; Never[never - bottom type]
 String --&gt; Never
 Boolean --&gt; Never
 Object --&gt; Never
 Tuple --&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>TypeScript: Genéricos y código reutilizable</title><link>https://blog.dacadev.com/programacion/typescript/genericos/</link><pubDate>Sat, 20 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/programacion/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/programming/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["MyMap&amp;lt;K, V&amp;gt;"] --&gt; A["MyMap&amp;lt;string, number&amp;gt;"]
 G --&gt; B["MyMap&amp;lt;string, boolean&amp;gt;"]
 G --&gt; C["MyMap&amp;lt;number, Hero&amp;gt;"]
&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/programacion/typescript/clases-e-interfaces/</link><pubDate>Fri, 19 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/programacion/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/programming/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>TypeScript: Interfaces y contratos de tipos</title><link>https://blog.dacadev.com/programacion/typescript/interfaces/</link><pubDate>Thu, 18 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/programacion/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/programming/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,&lt;br/&gt;implements o merging?}
 Q -- Sí --&gt; I[Usa interface]
 Q -- "No (uniones, tuplas, mapeos)" --&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>TypeScript: Funciones, parámetros y generadores</title><link>https://blog.dacadev.com/programacion/typescript/funciones/</link><pubDate>Wed, 17 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/programacion/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/programming/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>TypeScript: Objetos y tipos personalizados</title><link>https://blog.dacadev.com/programacion/typescript/objetos-y-tipos-personalizados/</link><pubDate>Tue, 16 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/programacion/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/programming/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] --&gt; A[flash: Hero]
 T --&gt; B[superman: Hero]
 T --&gt; C[...otros héroes]
 note["Un cambio en Hero&lt;br/&gt;se propaga a todos"] -.-&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/programacion/typescript/tipos-basicos/</link><pubDate>Mon, 15 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/programacion/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/programming/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["A | B"]
 U[Cualquier valor que sea A, B o ambos]
 end
 subgraph Inter["A &amp; B"]
 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>TypeScript: Introducción y configuración del entorno</title><link>https://blog.dacadev.com/programacion/typescript/introduccion-a-typescript/</link><pubDate>Sun, 14 Jun 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/programacion/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/programming/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] --&gt; B[AST de TypeScript]
 B --&gt; C{Typechecker}
 C -- válido --&gt; D[JavaScript emitido]
 C -- error --&gt; E[Error en compilación]
 D --&gt; F[AST de JavaScript]
 F --&gt; G[Bytecode]
 G --&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></channel></rss>