1

我有点想知道,为什么没有其他人有这个问题,或者我只是没有用正确的词来描述它。问题是,我有一个发布到 npm 的模块,它必须有版本。一个可以通过 system-js 加载并直接从 npm 使用,另一个版本是我使用 system-js-builder 创建的自执行包。

假设模块名为@company/foo 我在根文件夹中有一个 index.ts,它只是从 src 导出所有内容,我还有一个 index.ts 导出所有子模块。所以 index.ts 看起来像这样。

export * from "./src/";

在我想使用的模块中,我可以简单地使用以下内容。

import { bar } from "@company/foo";

到目前为止很容易。不,我从我的索引创建了一个自执行包,并给它一个全局名称foo ,这样如果我将脚本添加到页面中或与其他脚本连接,我就可以调用foo.bar() 。这也很好用。但是现在我有一个问题,我不知道如何为这个包创建类型。我的想法是做类似的事情

declare namespace foo {
    export * from "./src/";
}

我认为这很好地描述了捆绑的作用。但是打字稿不喜欢这样。我也尝试了一些模块,但没有任何效果。我该如何描述从我的 src 桶中导出的内容以命名空间 foo 为前缀的事实?

我希望很清楚我想要达到的目标。

4

2 回答 2

1

您需要在package.json.

  1. main-- 告诉模块加载器模块的入口点是什么,而不是index.js.
  2. typings-- 为模块设置 TypeScript 定义文件。

例如,假设我们有一个@company/foo包含以下字段的模块package.json

{
    "main": "lib/bundle.js",
    "typings": "index.d.ts"
}

现在在你的tsconfig.json,你想要moduleResolution设置:

{
    "moduleResolution": "node"
}

当您从 导入时@company/foo

import { bar } from '@company/foo';

在您的index.d.ts中,您应该有这一行来声明 bar:

declare function bar();

TypeScript 将尝试barnode_modules/@company/foo/index.d.ts.

更新:

这是从不同模块重新导出单个函数/对象并导出命名空间的完整示例。这个文件应该被调用index.d.tsmain.d.ts等等,所以它被 TypeScript 识别为环境定义。

import * as another from './src/another';
declare namespace hello {
  function bar();

  interface ProgrammerIntf {
    work();
    walk();
    play();
  }

  class Programmer implements ProgrammerIntf {
    work();
    walk();
    play();
  }

  export import world = another.world;
}

export default hello;

要使用这个命名空间,在调用者脚本中,

import hello from '@company/foo';
hello.bar();
hello.world();
let programmer = new hello.Programmer();

更新 2:

我在TypeScript 的文档中找到了一种我以前没有注意到的方法。

您可以在global范围内声明所有类型,如下所示:

import * as another from './src/another';

declare global {
  namespace hello {
    function bar();

    interface ProgrammerIntf {
      work();
      walk();
      play();
    }

    class Programmer implements ProgrammerIntf {
      work();
      walk();
      play();
    }

    export import world = another.world;
  }
}

然后在调用者脚本中,只需使用:

import '@company/foo';
hello.bar();
hello.world();
let programmer = new hello.Programmer();

当然,如果你在你的包的开头捆绑声明,你应该可以hello直接使用而不需要导入语句。

于 2016-12-02T15:41:16.443 回答
0

如果我理解正确,您需要一个全局变量foo,其中包含module.

您可以通过declare var和来实现typeof

import * as _foo from './src'
declare var foo: typeof _foo
// implement self-executing logic

导入自执行代码后,全局变量 foo 将可用于正在编译的项目中的所有文件。

对于 JavaScript 文件,只要您实现了可以访问的逻辑,它们就不会输入感知foo

于 2016-12-07T11:40:24.120 回答