ProgramaciónDesarrollador Frontend

¿Qué son los archivos de declaración en TypeScript, cuándo y por qué escribir archivos .d.ts personalizados? ¿Cómo estructurar una descripción de tipos personalizada para módulos JS externos?

Supere entrevistas con el asistente de IA Hintsage

Respuesta.

Historia de la cuestión:

Muchas bibliotecas del ecosistema JavaScript solo proporcionan archivos js fuente, sin tener tipos propios. Para describir los tipos de bibliotecas externas o personalizadas, así como variables globales, TypeScript implementa un formato especial de archivos con la extensión .d.ts (archivos de declaración). Se han convertido en el estándar para proporcionar información de tipos y seguridad de tipos en proyectos sobre cualquier módulo js.

Problema:

Si los tipos para módulos JS externos no están definidos, TypeScript se ve obligado a interpretar tales importaciones como any, lo que significa que pierdes todas las ventajas de la tipificación estática: errores en llamadas, campos inexistentes, parámetros incorrectos lógicamente pasan la compilación y solo se detectan después de ejecutar el código. También es imposible hacer autocompletado y navegación por tipos.

Solución:

Con los archivos de declaración se pueden describir manualmente los tipos para cualquier código JS: funciones, clases, objetos, espacios de nombres e incluso constantes globales. De esta manera, el proyecto permanece seguro en términos de tipos, independientemente del origen de la biblioteca externa.

Ejemplo de código:

// hello.d.ts declare module 'hello' { export function sayHello(name: string): string; } // app.ts import { sayHello } from 'hello'; sayHello('TypeScript'); // Tipo seguro

Características clave:

  • Separa la descripción de las firmas y estructuras de tipos de la implementación (código JS fuente);
  • Permiten implementar una tipificación estricta incluso en compilaciones externas/antiguas;
  • En los archivos .d.ts, la implementación está prohibida, solo las firmas/descripciones.

Preguntas capciosas.

¿Se pueden declarar implementaciones de funciones directamente en el archivo de declaración?

No, en los archivos de declaración solo se permite la declaración de estructuras y firmas, no su implementación. Cualquier cuerpo de funciones o constructores generará un error de compilación.

// No se puede: declare function sum(a: number, b: number) { return a + b; }

¿Dónde buscar tipos para módulos npm populares si no están en el paquete fuente?

En el repositorio DefinitelyTyped (paquete npm @types/<lib>): casi todos los paquetes populares tienen typings actuales en forma de módulos npm separados.

¿Se pueden describir variables globales (no a través de import), utilizando un archivo d.ts?

Sí, a través del mecanismo de declaraciones ambient, por ejemplo, declare var VERSION: string;. Esto es conveniente para describir window.X, constantes y variables globales.

Errores de tipos y anti-patrones

  • Escribir cuerpos de funciones y clases en archivos d.ts;
  • Describir firmas incompletas o desactualizadas, causando conflictos con la estructura real;
  • Conectar diferentes typings para un mismo módulo/variable global, causando conflictos de tipos.

Ejemplo de la vida real

** Caso negativo En el proyecto se utiliza una biblioteca JS sin typings. Los desarrolladores olvidaron el archivo d.ts y acceden a la API a través de any. Surgen errores al actualizar la biblioteca: las llamadas antiguas se rompen, pero el compilador no lo detecta.

Ventajas:

  • Inicio rápido, no se requiere descripción adicional.

Desventajas:

  • Errores ocultos, comportamiento implícito, depuración difícil en grandes volúmenes de código.

** Caso positivo Se desarrolló un archivo d.ts propio para la biblioteca actual, las firmas se mantienen actualizadas, se utiliza autocompletado y navegación en la IDE.

Ventajas:

  • Seguridad completa de tipos, los errores son visibles instantáneamente al cambiar la API;
  • Acelera el desarrollo, se pueden incorporar nuevos desarrolladores sin un profundo estudio del código JS.

Desventajas:

  • Mantenimiento separado de archivos d.ts, es necesario seguir la sincronización al actualizar bibliotecas JS.