Búsqueda de sitios web

javascript - typescript: usando archivos de declaración en un proyecto de typescript para exponer tipos globalmente


Recientemente he comenzado a trabajar con TypeScript. Tengo un proyecto de TypeScript configurado que tiene muchos componentes de React escritos con TypeScript. Estos componentes de TypeScript usualmente exportan el propio componente y, para que el desarrollo sea más conveniente, he extraído todos los tipos necesarios para este componente de TypeScript a un archivo separado. Ahora, normalmente tendrías que importar estos tipos en tu componente para usarlos, pero como resultaba engorroso, alguien del equipo tuvo la idea de nombrar a este archivo separado que contiene los tipos como types.d.ts (o cualquier_otro.d.ts). Esto hace que los tipos estén disponibles globalmente en todo el proyecto, sin necesidad de importar explícitamente los tipos en ningún lugar.

Ahora, entiendo que los archivos de declaración de tipos solo son necesarios en caso de que esté utilizando un componente de JavaScript en mi proyecto de TypeScript, y si quiero que la verificación de tipos funcione para ese componente de JavaScript. En ese caso, puedo obtener el archivo de declaración de tipos desde fuera (como, DefinitelyTyped), o puedo crear un archivo de declaración local. Esto no es para lo que estoy usando un archivo de declaración aquí.

Pero me gustaría entender cuáles son los problemas con este uso?

  • ¿Está mal exponer todos los tipos de forma global (Tenga en cuenta que la mayoría de estos tipos solo son necesarios internamente por el componente, solo algunos son necesarios por otros componentes que consumen este componente)?
  • ¿Va a haber algún problema con el compilador o la configuración de TypeScript debido a esto?
  • He leído sobre una opción de compilador que genera los archivos de declaración, ¿puede esta configuración interferir con eso?

NOTA: Este archivo separado que se llama d.ts en realidad no sigue ninguna guía específica que pueda ser requerida para archivos de declaración. Esto solo tiene algunas declaraciones de interfaces regulares

Respuesta #1

Algunas observaciones:

  • en un archivo .ts (o un archivo d.ts), si no hay una exportación a nivel superior, se consideraría un script global (similar a cómo funciona esto en JavaScript) y todo en el script estaría disponible globalmente. Así es como los tipos se exponen globalmente en mi caso (nuevamente, no tiene que ser un archivo .d.ts)

  • si tienes un archivo ts y un archivo d.ts con el mismo nombre, el compilador ignora el archivo d.ts y es por eso que no es posible exponer tipos para Component.tsx usando Component.d.ts (tendrías que nombrar el archivo d.ts de otra manera)

  • cuando se importa un módulo externo sin información de tipos, TypeScript sugiere agregar un archivo d.ts con declare module moduleName, en lugar de esto también puedes simplemente agregar un archivo .d.ts regular con una exportación de nivel superior dentro de moduleName/index.d.ts

Entonces, para responder a mis preguntas:

  • No estaría mal exponer todos los tipos utilizados globalmente dentro de tu aplicación, pero entonces tienes que tener cuidado con cualquier conflicto de nombres/espacios de nombres. En este caso, no es necesario usar un archivo d.ts, esta configuración también funcionaría con un archivo .ts que exponga los tipos globalmente. Otra manera de lograr esto sería exportar los tipos desde los archivos respectivos e importarlos donde se requiera.

  • en esta configuración, el único problema con el compilador que puede surgir es cuando el archivo .d.ts tiene el mismo nombre que el archivo .ts, en cuyo caso el archivo .ts lo sobrescribiría y los tipos del .d.ts no estarían disponibles globalmente.

  • el compilador genera los archivos de declaración a partir de archivos ts, y eso se requiere principalmente si necesitas publicar tus tipos. En nuestro caso, los tipos son internos y realmente no necesitaremos generar las declaraciones. Nuestro uso, como se discutió, no depende de que el archivo sea un archivo de declaración, funcionará igual de bien en un archivo .ts y no deberíamos estar usando un archivo .d.ts para esto. Así que, no, no habría ningún impacto.

Respuesta #2

El equipo de TS está en contra de esta práctica, TS ve los archivos .d.ts como un asociado del archivo .js solo para proporcionar seguridad de tipos.

Esto también tiene pocos problemas

  1. No habrá verificación de tipos para este archivo si usas la opción skipLibCheck en tu tsconfig

  2. Los archivos .d.ts son para colocar cosas en el ámbito global o alterar los ámbitos globales en tus proyectos, así que digamos que escribes algún tipo en .d.ts, estará disponible para todos los componentes en tu código.

  3. Digamos que hay múltiples archivos .d.ts en tu código y si hay múltiples interfaces con el mismo nombre, se fusionarán (en el caso de interface) y pueden generar errores inesperados.

También hay un hilo en el repositorio de TypeScript para esta misma discusión https://github.com/microsoft/TypeScript/issues/52593