Cómo sobrescribir el tipo de propiedad de una interfaz desde .d.ts en TypeScript: Guía completa

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é no puedes simplemente cambiar el tipo?

\n\n

Imagina la situación: estás integrando una potente biblioteca para trabajar con gráficos. Tiene documentación perfecta, cientos de estrellas en GitHub, e incluso archivos .d.ts con la descripción de los tipos. Pero hay un problema: el desarrollador de la biblioteca decidió que el campo data debe ser string | number, pero tú necesitas estrictamente Date. Entras en node_modules, modificas el archivo y todo se rompe con el próximo npm install.

\n\n

¿Te suena familiar? Es uno de los problemas más comunes que enfrentan los desarrolladores de TypeScript. La pregunta «Overriding interface property type defined in Typescript d.ts file» ha acumulado miles de visitas en Stack Overflow. Y con razón: el diablo está en los detalles.

\n\n

En este artículo, analizaremos 5 formas legales de sobrescribir el tipo de propiedad de una interfaz desde un archivo .d.ts externo. Sin trucos de copiar archivos, solo TypeScript puro.

\n\n

Comprendiendo el problema: ¿Por qué TypeScript se resiste?

\n\n

Antes de romper el sistema, entendamos su lógica. TypeScript es estricto con los tipos no por malicia, sino por tu seguridad. Cuando intentas sobrescribir una propiedad de una interfaz, básicamente estás declarando: «Yo sé mejor que el autor de la biblioteca». Y TypeScript pregunta: «¿Estás seguro? Pruébalo».

\n\n

Consideremos un ejemplo clásico. Supongamos que tenemos una interfaz de una biblioteca:

\n\n
// node_modules/some-library/types.d.ts\nexport interface UserConfig {\n  id: string | number;\n  name: string;\n  createdAt: Date | string;\n  metadata: Record<string, unknown>;\n}
\n\n

Quieres que createdAt sea solo Date. La herencia simple no funcionará: TypeScript dará un error si intentas reducir el tipo. Pero hay soluciones alternativas.

\n\n

Método 1: Declaration Merging (fusión de declaraciones)

\n\n

La forma más elegante, cuando es posible. Si la biblioteca exporta una interfaz, no un tipo (type), puedes «complementarla» en el ámbito global o en un módulo.

\n\n

Condición importante: las interfaces con el mismo nombre en el mismo ámbito se fusionan automáticamente. Pero no se puede sobrescribir una propiedad existente, solo agregar una nueva.

\n\n

Por lo tanto, este método es adecuado cuando necesitas extender la interfaz, no cambiar un campo existente. Por ejemplo:

\n\n
// global.d.ts\nexport interface UserConfig {\n  customField: boolean; // ✅ Agregamos un nuevo campo\n}\n\n// Pero así es un error:\nexport interface UserConfig {\n  createdAt: Date; // ❌ Error: duplicación de identificador\n}
\n\n

Conclusión: Declaration Merging es una excelente herramienta para agregar campos, pero inútil para sobrescribir los existentes.

\n\n

Método 2: Uso de Omit y una interfaz propia

\n\n

Esta es la bala de plata para el 90% de los casos. La idea es simple: «recortamos» la propiedad problemática mediante Omit y creamos un nuevo tipo con el tipo deseado.

\n\n
// Tu código\ntype MyUserConfig = Omit<UserConfig, 'createdAt'> & {\n  createdAt: Date; // ✅ Ahora solo Date\n};\n\n// Uso\nconst config: MyUserConfig = {\n  id: 42,\n  name: 'Alice',\n  createdAt: new Date('2024-01-01'), // Funciona\n  metadata: { role: 'admin' }\n};
\n\n

¿Qué sucede aquí? Omit<UserConfig, 'createdAt'> crea un tipo sin el campo createdAt. Luego, mediante la intersección de tipos (&), agregamos este campo de nuevo, pero con el tipo deseado.

\n\n

Ventajas: ideal para cambios puntuales, no afecta la interfaz original.
\nDesventajas: si hay muchas propiedades, el código se vuelve voluminoso.

\n\n

Método 3: Extensión mediante Pick y Partial

\n\n

A veces es necesario sobrescribir no una, sino varias propiedades. O quieres hacer que todos los campos sean opcionales,

Blogs

Book Recommendations