ProgramaciónDesarrollador Typescript

Hable sobre el mecanismo de fusión de declaraciones (Declaration Merging) en TypeScript. ¿Cómo funciona para interfaces, funciones y espacios de nombres (namespace), y cuáles son las trampas aquí?

Supere entrevistas con el asistente de IA Hintsage

Respuesta.

Declaration Merging (fusión de declaraciones) es un mecanismo único de TypeScript que permite combinar declaraciones con el mismo nombre en un solo tipo/entidad. Esto funciona para interfaces, espacios de nombres y funciones.

  1. Interfaces: las declaraciones de la interfaz con el mismo nombre se fusionan en una única interfaz grande:
interface User { name: string; } interface User { age: number; } const u: User = { name: 'Vasya', age: 42 }; // OK
  1. Funciones + namespace: una función y un espacio de nombres con el mismo nombre se fusionan: los métodos estáticos se agregan:
function helper() {} namespace helper { export function extra() {} } helper.extra(); // OK
  1. Namespace + enum y namespace + class: también es posible la fusión para extender clases y enums con propiedades estáticas.

Pregunta capciosa.

¿Cómo ocurre la fusión de métodos con el mismo nombre en diferentes espacios de la interfaz, y qué pasará si sus firmas son diferentes?

Respuesta:

Si declara en diferentes interfaces de fusión métodos con el mismo nombre, TypeScript intentará "sobrecargar" estos métodos en la interfaz final. Sin embargo, si las firmas son incompatibles (no se pueden sobrecargar), esto resulta en un error de compilación.

Ejemplo:

interface Foo { bar(a: number): void } interface Foo { bar(a: string): void } // OK: sobrecargas interface Foo { bar(a: number[]): void } // Error: firmas incompatibles

Ejemplos de errores reales debido al desconocimiento de los matices del tema


Historia

En un proyecto se ampliaba la interfaz Window de terceros a través de la fusión de declaraciones para diferentes características: un equipo agregó window.myFeature: boolean, otro window.myFeature: number. La fusión causó un error de tipos, y el compilador detectó el conflicto solo en la compilación final: alguien tuvo que hacer un cambio rápido de nombre.


Historia

Por error, se declararon dos interfaces ArrayHelper con diferentes firmas de métodos, esperando que se combinara en "ambas opciones disponibles". En realidad, la primera firma anuló la segunda, lo que llevó a una autocompletación incorrecta en IDE y un error durante la integración con un nuevo módulo.


Historia

Al usar un espacio de nombres para "ampliar" una función a través de la fusión de declaraciones, un desarrollador declaró incorrectamente export dentro del namespace, y la función resultó ser inaccesible. Solo después de la revisión se dieron cuenta de que sin el export correcto la fusión no funciona y las propiedades no aparecen en la función.