Cuando trabajamos con TypeScript y queremos importar módulos de JavaScript, a menudo nos encontramos con que algunos módulos se importan sin problemas, mientras que otros nos dan errores. Esto suele ocurrir porque TypeScript necesita conocer los tipos de las funciones o variables que estamos importando, y el código JavaScript puro no incluye esa información. Para solucionar esto, existen los archivos de definición con extensión .d.ts.
Estos archivos .d.ts no contienen código ejecutable, sino que describen la forma y los tipos de las funciones, clases o variables que existen en un módulo JavaScript. Por ejemplo, si tenemos una función llamada tokenToDate que acepta un string y un Date y devuelve un Date, el archivo .d.ts declarará esa función con la palabra clave declare, indicando a TypeScript qué tipos esperar sin necesidad de ver el código fuente real.
Cuando instalamos paquetes desde npm, es fundamental que estos incluyan sus propios archivos .d.ts para que TypeScript pueda entenderlos correctamente. Algunos paquetes están escritos en TypeScript y ya incluyen estos archivos, pero otros, que solo tienen código JavaScript, no los traen. En esos casos, TypeScript no sabe qué tipos tienen las funciones o variables, lo que genera errores al importar.
Para resolver este problema, podemos hacer dos cosas. Primero, en el archivo tsconfig.json, existe una opción llamada allowJs que permite a TypeScript procesar archivos JavaScript, pero esta opción no siempre funciona bien y no es la solución ideal. La segunda opción, más fiable, es instalar los tipos desde el repositorio DefinitelyTyped, que es una comunidad que mantiene definiciones de tipos para muchos paquetes populares. Estos paquetes se instalan con un nombre que empieza por @types/ seguido del nombre del paquete original. Por ejemplo, para un paquete llamado isode, instalaríamos @types/isode como dependencia de desarrollo. Esto añade el archivo .d.ts correspondiente y elimina los errores de importación.
Además, cuando desarrollamos nuestros propios proyectos en TypeScript y queremos distribuirlos para que otros los usen, es importante generar estos archivos .d.ts para que los consumidores de nuestro código puedan beneficiarse de la información de tipos. Para ello, configuramos el tsconfig.json activando la opción declaration. Así, al compilar con tsc, se generarán automáticamente los archivos .d.ts junto con los archivos .js transpilados.
Por ejemplo, si tenemos un archivo calculadora.ts que exporta funciones como sumar, restar y multiplicar, al compilar con la opción de declaración activada, obtendremos un archivo calculadora.d.ts que declara estas funciones con sus tipos correspondientes. Esto es esencial para que otros proyectos TypeScript puedan importar y usar nuestro código sin perder la información de tipos.
// calculadora.ts
export function sumar(a: number, b: number): number {
return a + b;
}
export function restar(a: number, b: number): number {
return a - b;
}
export function multiplicar(a: number, b: number): number {
return a * b;
}
Al compilar con la opción declaration: true en tsconfig.json, se generará un archivo calculadora.d.ts similar a este:
export declare function sumar(a: number, b: number): number;
export declare function restar(a: number, b: number): number;
export declare function multiplicar(a: number, b: number): number;
De esta forma, aunque solo distribuyamos el código JavaScript, los usuarios de TypeScript podrán conocer los tipos y evitar errores.
En definitiva, los archivos .d.ts son la clave para que TypeScript pueda trabajar con módulos JavaScript sin perder la información de tipos. Ya sea instalando los tipos desde @types o generando nuestros propios archivos de definición, asegurarnos de que estos archivos estén disponibles es fundamental para una experiencia de desarrollo fluida y sin errores. Además, automatizar la generación de estos archivos con la configuración adecuada nos ahorra trabajo y reduce la posibilidad de errores humanos.