TypeScript:如何从子模块导入类?

时间:2016-08-25 20:46:53

标签: javascript typescript ecmascript-6

我有一个使用.ts.d.ts文件的TypeScript应用程序。使用三次斜杠表示法/// <reference path=...>进行引用。我的应用程序具有以下定义文件:

declare module APP {

    class Bootstrap {
        constructor();
    }

}

然后我声明了一个名为"app"的模块,以便我可以将其导入其他文件中:

declare module "app" {
    export = APP;
}

假设我的Bootstrap类存在,那么我使用以下方法导入Bootstrap类:

import { Bootstrap } from 'app';

这样做。

现在我在APP上创建一个子模块,如下所示:

declare module APP.Service {
    class Async {
        constructor();
    }
}

我为子模块做了另一个声明:

declare module "app/service" {
    export = APP.Service;
}

现在,当我像这样导入类Async时:

import { Async } from 'app/service';

我收到以下错误消息:

Module '"app/service"' resolves to a non-module entity and cannot be imported using this construct.``

如何从子模块导入类?

我通过声明全局var

找到了解决方法
declare var APP_SERVICE: APP.Service.IService; // IService exists

在我的模块上导出:

declare module "app/service" {
    export = APP_SERVICE;
}

这样做的缺点是我的全局命名空间受到var我不能使用的污染,因为我会使用Service通过{{1 }},而不是App.Service

1 个答案:

答案 0 :(得分:2)

如果您关心为模块创建一个漂亮,可重用,可维护的声明文件,首选方法是使用typings,因为它可以很好地处理类型依赖关系管理和子模块等方面。

  1. 为您正在编写的类型创建单独的存储库。
  2. 添加typings.json文件,其中包含主要输入的名称和路径。例如:

    {
      "name": "my-main-module",
      "main": "index.d.ts"
    }
    
  3. 将主模块的类型声明添加到index.d.ts,将子模块的类型声明添加到submodule-name.d.ts

    <强> submodule.d.ts

    export interface submoduleInterface {
      someProp: number
    }
    

    <强> index.d.ts

    import * as submodule from './submodule'
    
    export interface mainInterface {
      someProp: number
    }
    
  4. 运行typings bundle index.d.ts -o bundle.d.ts。这会将您的所有打包捆绑到一个类型声明文件中,声明正确的子模块并尊重模块,子模块甚至外部模块之间的所有必要依赖关系。

  5. 将此文件复制到原始项目中的custom-typings目录,或将此回购提交给typings registry,以便其他人也可以从中获利,并以正常方式将其拉入typings i my-module-name

  6. 以下是包含所有代码的gist以及生成的bundle.d.ts。这是一个repo,它使用两个子模块(redux-persist/constants)作为外部依赖项(redux),并最终提交给打字机注册表。