Javascript 如何使用Typescript和NodeJS将模块注入类中

Javascript 如何使用Typescript和NodeJS将模块注入类中,javascript,node.js,typescript,module,Javascript,Node.js,Typescript,Module,我正在开发nodeJS+Typescript。我有一个面向对象的背景,我想从nodejs模块中获益,但我很难将它们与不应该是模块的类混合在一起 这就是我想做的: foo.ts(模块) bar.ts(不应该是模块) server.js(节点启动文件) 我在尝试这样构造代码时面临的问题: 条看不到Foo。我试图添加对该文件的引用,但无效 当我导入./foo时,它“起作用”,但当我这样做时,Bar在同一名称空间上定义的其他文件中看不到其他导出的类型(即使我写入类型的全名,即包含名称空间,它仍然看不到

我正在开发nodeJS+Typescript。我有一个面向对象的背景,我想从nodejs模块中获益,但我很难将它们与不应该是模块的类混合在一起

这就是我想做的:

foo.ts(模块)

bar.ts(不应该是模块)

server.js(节点启动文件)


我在尝试这样构造代码时面临的问题:

  • 看不到Foo。我试图添加对该文件的引用,但无效
  • 当我导入./foo时,它“起作用”,但当我这样做时,Bar在同一名称空间上定义的其他文件中看不到其他导出的类型(即使我写入类型的全名,即包含名称空间,它仍然看不到)
  • 因此,我删除了Bar中的名称空间Ns,当我用名称空间键入名称时,可以看到其他类型。但是现在,Bar是一个模块,我觉得它就像我的构造函数注入一样,因为Foo是导入的,我可以直接实例化它

  • 我不想强制我的标准。我想知道我正在尝试做的事情的正确方法是什么。这场斗争让我觉得,在开发nodejs应用程序时,我有义务重新设计并完成所有模块。是这样吗

    如果我应该使用完整的模块,我应该如何管理依赖注入


    谢谢

    为了充分利用面向对象编程的强大功能(或者更好地说,或者说是面向协议的编程),您应该使用
    接口Foo
    隐藏使用
    Bar
    类的特定实现
    MyFoo

    福茨

    export interface Foo {
      fooMethod(): number;
    }
    
    MyFoo.ts

    export class MyFoo {
      fooMethod(): number {
        return 1;
      }
    }
    
    酒吧

    import {Foo} from './Foo'
    
    export class Bar {
      constructor(private foo: Foo) {}
    
      barMethod(): number {
        return this.foo.fooMethod();
      }
    }
    
    其他地方:

    import {Boo} from './Boo'
    import {MyFoo} from './MyFoo'
    
    const result = new Boo(new MyFoo()).barMethod();
    

    我个人不建议使用名称空间。您可以阅读有关名称空间和模块的更多信息。

    我明白您的观点。这种方法效果很好,看起来确实是推荐的方法。然而,乍一看,这种模式让我觉得,如果我使用许多小型内聚类(每个类在一个单独的文件中)和许多注入级别,我可能会遇到某种“导入地狱”。您知道这是否是一个真正的问题吗?您将有许多小模块(类),它们中的每一个都将依赖于作为接口注入的许多其他模块(如
    类栏
    依赖于
    接口Foo
    )。这个数字越小,你的模块耦合就越低,你的软件设计就越好。很好的解释。再次感谢你。因此,我可以(1)为一个模块创建接口,并且有一个缺点,就是即使我打算为它提供一个单一的实现,也会有接口,或者(2)绕过接口,导入并引用具体类型以利用intellisense,但是有一个缺点,就是将类型加载到Bar的范围内,甚至不打算实例化它。我的想法正确吗?是的。此外,如果您为软件编写测试,那么理想情况下,每个接口至少有2个实现—一个或多个真实实现和一个或多个假实现,用于测试依赖于这些接口的类。
    export class MyFoo {
      fooMethod(): number {
        return 1;
      }
    }
    
    import {Foo} from './Foo'
    
    export class Bar {
      constructor(private foo: Foo) {}
    
      barMethod(): number {
        return this.foo.fooMethod();
      }
    }
    
    import {Boo} from './Boo'
    import {MyFoo} from './MyFoo'
    
    const result = new Boo(new MyFoo()).barMethod();