当“不要这样做”不是一个选项时,如何将Typescript名称空间与外部模块混合

时间:2016-11-12 08:29:07

标签: node.js typescript namespaces node-modules

情况

我有一个使用命名空间编写的Typescript应用程序。我想将一些逻辑(Google OAuth)移出客户端并转移到节点服务中。我为here创建了一个几乎完整的项目。

这个新项目有一个节点组件,它将使用密钥和客户端组件向谷歌发出授权请求,这些组件可以被与服务器通信的其他应用程序重用。我还有一个testHarness应用程序,它使用此客户端对其进行测试,并确保我可以在基于命名空间的应用程序中使用它。

我有一些客户端和服务器都使用的共享接口。

我希望我的客户端代码可以在使用externam模块和命名空间的项目中使用 - 即我现有的项目。

一定是可能的

我在很多地方读过

  

不要在外部模块中使用“名称空间”。

     

不要这样做。

     

严重。停止。

比如answer,但我仍然相信这一定是可能的。我认为这是因为在我的项目中我依赖于RxJs。客户端和服务器都使用我的node_modules文件夹中的这个项目。

我尝试了什么

在我的project我有一个contracts.d.ts文件,我想在客户端和服务器之间共享。

的StackOverflow

我看了这个问题:

Typescript es6 import module "File is not a module error"

并使我的合同看起来像这样:

// test.js - exporting es6
export module App {
  export class SomeClass {
    getName(): string {
      return 'name';
    }
  }
  export class OtherClass {
    getName(): string {
      return 'name';
    }
  }
}

然后尝试列出的各种导入方法:

import * as app1 from "./test";
import app2 = require("./test");
import {App} from "./test";

我让每一个都工作,以便我的服务器和客户端正确编译,但一旦我尝试编译我的testHarness应用程序 - 使用命名空间 - 它失败了:

src/testHarness/testHarness.ts(4,38): error TS2304: Cannot find name 'PricklyThistle'.
src/testHarness/testHarness.ts(4,38): error TS2503: Cannot find namespace 'PricklyThistle'.

从node_modules

复制声明文件

正如我所说,我确信这是可能的,因为我导入到node_modules的依赖项被我的客户端和服务器项目使用,而我的客户端仍然可以与内部命名空间一起使用。

要沿着这条路线走下去,我在Rx ts文件夹中编辑了一个d.ts文件并添加了一个新界面。我验证了客户端和服务器都可以使用此接口,并且我的testHarness应用程序(带有名称空间)可以编译。一切都很好!

然后我将此编辑的文件复制到我的公共文件夹中。我不得不重命名模块以避免冲突,但后来我得到了:

src/node/youTubeAuthenticationServer.ts(3,23): error TS2306: File '/src/common/rx.test.d.ts' is not a module.

我编辑的声明文件如下:

declare module RxTest {

    export interface TestInterface{
        propertyOne: string;
        propertyTwo: number;
    }

}
declare module "rx.test" { export = RxTest; }

解决方法

现在我刚刚复制了两个应用程序使用的接口。这是有效的,只有2个小接口,所以这不是什么大不了的事。但这非常令人沮丧。关于节点的一个好处是使用与浏览器相同的语言。如果你不能分享不好的代码。我还有其他更大的代码库,我想做类似的事情,在这些情况下,复制代码将不是一个可行的解决方案。

我工作的任何新项目都会使用外部模块,但在处理遗留代码时,这并非总是可行。

我真的希望有人可以提供帮助。

由于

1 个答案:

答案 0 :(得分:0)

如果发现您的问题有点令人困惑,那么您所拥有的内容描述太多,示例(代码/配置)太少。

尝试这样做:

declare module "rx.test" {
    export interface TestInterface{
        propertyOne: string;
        propertyTwo: number;
    }
}

如果这不起作用,请编辑您的问题并添加您拥有的目录结构,您拥有的tsconfig.json文件,解释您如何构建(tsc,gulp等)等等上。