Dominando `window` en TypeScript: cómo agregar tu propia propiedad sin romper el código

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: ¿Por qué agregar una propiedad a window es un dolor de cabeza para todo desarrollador TypeScript?



Imagina la situación: estás escribiendo una aplicación SPA moderna en TypeScript. Todo va bien hasta que surge la necesidad de guardar un estado global o integrar un script externo (por ejemplo, analíticas, mapas o una pasarela de pago). Escribes:



window.myAppConfig = { apiKey: '123' };


Y entonces TypeScript te muestra un error rojo: "Property 'myAppConfig' does not exist on type 'Window & typeof globalThis'". ¿Te suena? Esta pregunta ha acumulado miles de visitas en Stack Overflow, y hoy no solo daremos una solución lista, sino que también exploraremos el interior de TypeScript para entender por qué sucede esto y cómo manejarlo de forma elegante y segura.



En este artículo, analizaremos varios enfoques, desde "parches" para principiantes hasta patrones profesionales utilizados por desarrolladores senior. ¡Allá vamos!



Bajo el capó: ¿Por qué TypeScript se queja de window.myProp?



Para entender el problema, debemos recordar que TypeScript es una extensión de JavaScript que añade tipado estático. El objeto window en el navegador es un objeto global que tiene un tipo predefinido (Window). Este tipo está descrito en las bibliotecas estándar de TypeScript (lib.dom.d.ts) e incluye todas las propiedades estándar: document, location, setTimeout y cientos más.



Cuando intentas asignar window.myProp, TypeScript verifica: "¿Existe esta propiedad en la interfaz Window?". Si no, es un error. Esto es una protección contra errores tipográficos y la contaminación accidental del ámbito global. Pero, ¿qué hacer si intencionalmente quieres extender window?



Método 1: El más simple, pero peligroso — as any



La primera opción que viene a la mente de un principiante es simplemente "callar" a TypeScript usando una conversión de tipo:



(window as any).myAppConfig = { apiKey: '123' };


Ventajas: rápido, funciona, no requiere definiciones adicionales.

Desventajas: pierdes todas las ventajas de TypeScript. Sin autocompletado, sin verificación de tipos. Si accidentalmente escribes myAppConfigg, no habrá error, pero la aplicación fallará en tiempo de ejecución. Es como desconectar las bolsas de aire de un coche: puedes conducir, pero es arriesgado.



Cuándo usarlo: solo para prototipado rápido o si estás seguro de que la propiedad se usará una sola vez y se eliminará.



Método 2: Extensión de la interfaz global (Interface Merging)



TypeScript admite la fusión de interfaces (declaration merging). Este es un mecanismo clave que permite "agregar" nuevas propiedades a un tipo Window ya existente. Para ello, debes declarar una interfaz con el mismo nombre en el ámbito global.



Crea un archivo global.d.ts (o agrégalo a cualquier archivo .d.ts de tu proyecto):



// global.d.tsinterface Window {    myAppConfig: {        apiKey: string;        debugMode?: boolean;    };    myAnalyticsFunction: (event: string, data: object) => void;}


Ahora puedes escribir:



window.myAppConfig = { apiKey: '123' };window.myAnalyticsFunction('page_view', { page: '/home' });

// TypeScript sugerirá que apiKey es un stringconsole.log(window.myAppConfig.apiKey); // ✅ Sin errores


¿Cómo funciona internamente? TypeScript fusiona automáticamente todas las declaraciones de interfaces con el mismo nombre. Si en lib.dom.d.ts ya existe interface Window { ... }, tu interfaz con el mismo nombre simplemente agregará nuevas propiedades. Esto se llama glob

Blogs

Book Recommendations