Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

376
Views
Cómo resolver dependencias circulares en mecanografiado

Configuración:

Imagina la siguiente configuración:

Hay una API que contiene, digamos, una carpeta foo y bar . Estas carpetas exportan todas sus cosas públicas a sus index.ts locales, que simplemente volverán a exportar las cosas públicas a través export * from [...] para que sea más conveniente.

En mi ejemplo, hay una dependencia circular, porque foo.ts requiere una parte de bar y viceversa, y entiendo perfectamente por qué es así .

Vea la captura de pantalla a continuación:

ingrese la descripción de la imagen aquí

Pregunta:

¿Cómo puedo resolver esto en un entorno con cientos de clases, funciones, constantes, tipos, enumeraciones, etc. de manera efectiva con TypeScript? Me imagino que necesito algún tipo de archivo de ayuda para resolver los puntos en común.

Incluso si creé algún tipo de carpeta foobar que requiere foo y bar y luego exporto todo a un gran archivo de exportación, probablemente se desordenará muy pronto. ¿Qué sucede si solo necesito bar o solo foo ? ¿Es una exportación con nombre lo suficientemente buena?

También quiero evitar problemas en el futuro, por lo que estoy buscando una solución sólida. La precedencia de llamadas no es el problema principal que trato de abordar aquí. Se trata más de cómo configurar las dependencias de una manera inteligente.

Meta:

Me gustaría usar foo y bar por separado y deberían poder compartir funciones/tipos/enumeraciones/interfaces, etc. entre sí.

Un fragmento de código muy simple se puede encontrar aquí:

codigosandbox.io

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

Perdón por el malentendido con el nombre. Desafortunadamente, tuve la oportunidad de ver nombres similares en aplicaciones reales y de alguna manera asumí erróneamente que también desea usar esta convención. Cuando se trata de "terminar con archivos enormes que tienen todo apilado o archivos súper pequeños". Esto es cuestión de encontrar un buen equilibrio. No me importan muchos archivos pequeños (módulos js), que se centran en una sola funcionalidad: es una señal de que uno ha destilado correctamente responsabilidades más pequeñas de un caso de uso más grande. Esto produce código que es más simple de entender, probar y mantener. Los archivos grandes (módulos js) o clases/funciones grandes son a menudo una señal de que SRP está roto. Con respecto al ejemplo de sandbox.io: no puedo entenderlo y no entiendo las intenciones detrás de las funciones hello y world . Son solo funciones simples que recursivamente se llaman entre sí (provocando un desbordamiento de pila). El refactor más simple sería simplemente usar una función compartida como, por ejemplo buildGreeting(msg1, msg2) ubicada en el directorio foobar . Exporte const world = 'world' desde el directorio foo , y const hello = 'hello' desde el directorio bar , luego, en algún otro directorio hermano, cree un módulo con una llamada como:

 import {hello} from '../foo' import {word} from '../bar' buildGreeting(hello, word);

Sin embargo, es un desafío ilustrar cualquier mejora significativa sobre este código de ejemplo, porque no ilustra ningún caso de uso real.

about 4 years ago · Juan Pablo Isaza Report

0

Su ejemplo parece ser bastante genérico, por lo que trato de describir algunas reglas generales, pero pueden ser de alguna manera obstinadas.

  1. Si hay una dependencia circular entre foo y bar el enfoque más simple para eliminarla es extraer todas las unidades circularmente dependientes en un módulo/directorio separado, por ejemplo, foobar . Mencionaste esta solución, pero la dirección de las dependencias debería ser diferente. Tanto foo como bar deben requerir foobar que proporcione el código compartido extraído. De esta manera, aún puede importar por separado foo y bar (importando transitoriamente foobar ).
  2. Esto se aplica también a todas functions/types/enums/interfaces que mencionó: si foo y bar usan algo, entonces debe colocarse en un módulo/directorio separado.
  3. Con respecto a nombres como functions/types/enums/interfaces , consideraría usar tales nombres como último recurso (por ejemplo, como nombres para directorios de hojas en el árbol de directorios), porque comunican información que la mayoría de las veces es irrelevante. Un enfoque mucho mejor es organizar (colocar) el código en torno a conceptos de dominio comercial en lugar de nombres relacionados con detalles de implementación. Esto aumenta la capacidad de descubrimiento del código y hace que la organización del código sea menos frágil. por ejemplo, en lugar de
 <sourcesRoot>/api/functions/getUser.ts <sourcesRoot>/api/functions/getPosts.ts <sourcesRoot>/api/enums/UserRole.ts <sourcesRoot>/api/types/User.ts <sourcesRoot>/api/types/Post.ts <sourcesRoot>/api/index.ts

... Considere usar:

 <sourcesRoot>/users/api/getUser.ts <sourcesRoot>/users/model/User.ts <sourcesRoot>/users/model/UserRole.ts <sourcesRoot>/users/index.ts <sourcesRoot>/posts/api/getPosts.ts <sourcesRoot>/posts/model/Post.ts <sourcesRoot>/posts/index.ts
  1. Mantenga foo y bar pequeños. Intente destilar algunos subdominios/áreas/contextos de foo o bar en directorios separados. Esto debería generar archivos index.ts más pequeños.
  2. Este puede ser obstinado e impopular... considere evitar los archivos de barril. En mi opinión, el archivo de barril funciona bien si publica una biblioteca. En tal caso, puede especificar miembros públicos con precisión (suponiendo que el módulo CommonJS). Sin embargo, los archivos de barril en los niveles inferiores del árbol de directorios no proporcionan mucho valor en mi opinión. Todavía puede importar módulos directamente (sin pasar por el archivo de barril). Hacen que la refactorización sea más lenta porque en muchos casos es necesario actualizar manualmente los archivos de barril. Si olvida actualizarlos, ocasionalmente crean una dependencia circular muy desagradable que en el tiempo de ejecución se manifiesta en forma de valores indefinidos. Es posible que tenga rutas de importación que se vean más limpias, pero en la práctica, rara vez se trabaja manualmente con rutas de importación. Este es un trabajo para el IDE.
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!