使用TypeScript通过JSDocs检查JS时,如何声明一个变量对应一个命名空间?

When using TypeScript to check JS via JSDocs, how to declare that a variable corresponds to a namespace?

在我的 JS 代码中,我导入了一个模块,如下所示:

const toolbox = require('../toolbox')

/**
 * @param {toolbox.Hammer} hammer
 */
function useHammer(hammer) {
  let nail = new toolbox.Nail()
  hammer.ham(nail)
}

现在,因为我的 tools/index.d.ts 文件将 toolbox 导出为命名空间。我的 IDE 可以看到 hammer 上有一个方法 ham。惊人的!但是它看不到toolbox里面有一个成员Nail

我尝试在 toolbox/index.js 中放置 @module@export 标签,但没有成功。我还尝试将 @type {toolbox} 放在 require 语句之上,但有人告诉我 toolbox is referenced directly or indirectly in its own type annotation.

如何让我的 IDE 知道 toolbox = require('toolbox') 使 toolbox 对应于我的命名空间?


一个例子toolbox/index.jstoolbox/index.d.ts供参考:

exports.Hammer = class {
  ham (nail) {
    if (Math.random() > 0.1) {
      exports.nailCount -= 1
      return 'bang!' 
    } else return 'Ouch my thumb!'
  }
}
exports.nailCount = 100
exports.Nail = class {}
export = toolbox
export as namespace toolbox

declare namespace toolbox {
  class Nail {}
  class Hammer {
    ham(n: Nail) : string
  }
}

还有我的 tsconfig(因为它有点货物文化)

{
  "compilerOptions": {
    "allowJs": true,
    "target": "es5",
    "checkJs": true,
    "baseUrl": "../",
    "moduleResolution": "node",
    "noEmit": true
  }
}

您正在使用哪个IDE?

VS Code 中,我可以看到 NailnailCount 显示为工具箱的一部分。

查看此图片:

此外,为了确保 hammer.ham 函数只接受一个 Nail 实例,在 [=17] 中的 Nail class 定义中添加一些 属性 =] 例如。

// toolbox/index.d.ts

export = toolbox;
export as namespace toolbox;

declare namespace toolbox {
  class Nail {
    length: string; // new property added
  }
  class Hammer {
    ham(n: Nail): string;
  }
}

现在,在 main/index.js 中,如果我们传递 Nail 实例以外的任何内容,我们将收到错误消息。 例如

const toolbox = require("../toolbox");

/**
 * @param {toolbox.Hammer} hammer
 */
function useHammer(hammer) {
  let nail = new toolbox.Nail();
  hammer.ham("nail-string"); // this will show a red squiggle under "nail-string" since it is a string and the compiler expected a Nail instance
}

查看此图片: