我想在Visual Studio Code中使用依赖模块的类型定义(在Javascript的Node.js中)
本文是关于cloudpack方便日历2019年的文章。
这个标题很难。没有自信能够传达自己想做什么。
我以前在 Qiita 上写了一篇关于在 VS Code 上进行 JavaScript 类型判断的文章。
这篇文章没有提到,但它包含了一个问题:这个怎么做呢?
我想做的事情
-
依存モジュールのtypeやinterfaceで定義された情報をローカル変数の型に指定したい
指定した型に基づいてVisual Studio Codeに補完してほしい
Node.jsで
因为我在操作MongoClient时有这个想法,所以我以此为例。
因为经常忘记可以发送什么样的查询时,希望可以进行类型补全。
为此,我们提供了一个名为FilterQuery的类型,因此希望在JavaScript中也可以使用它。
// こんな感じで指定したら
/** @type {FilterQuery} */
const query = {
// ここで色々補完してほしい
}
试着补全
如果用Typescript的话就很容易了。
只需常规地导入并指定类型即可。
import { FilterQuery, MongoClient } from "mongodb";
interface User {
name: string
}
const client = new MongoClient("");
const query: FilterQuery<User> = {
}
这样做的话,在编辑查询内容时会像截图一样提供候选项。

我想用JavaScript实现与此相同的事情。
在Javascript的情况下
我尝试了许多不同的方法。
要求使用require导入
在JavaScript中,由于可以使用require进行加载,我以为以下方法可以行,结果行不通。
const mongo = require('mongodb')
/** @type {mongo.FilterQuery} */
const query = {}
如果使用`require`进行加载,则无法找到`FilterQuery`(无法访问)。
`const client = new mongo.MongoClient(“”);`是可见的。
在Javascript中,本来不存在的`export type ***`和`export interface ***`被隐藏了,所以无法看到它们。
因此,要求是不可能的。
导入(import)读取
如果使用JavaScript的ES6,同样可以使用import来实现,这样就能够完成补全。
import { FilterQuery, MongoClient } from "mongodb";
/** @type {FilterQuery} */
const query = {}
然而,它是无法运行的(没有意义)。
由于Node.js是使用CommonJS运行的,因此无法使用ECMA Script的模块系统。
(function (exports, require, module, __filename, __dirname) { import { FilterQuery } from "mongodb";
^
SyntaxError: Unexpected token {
在使用Node.js(v8.5.0或更高版本)时,似乎需要将文件扩展名命名为.mjs才能进行操作(在不使用Babel或webpack的情况下使用import/export – Qiita)。
这次我决定不使用这种方法。
在JSDoc中嵌入import语句(成功)
那么我们要怎么做呢,就是在JSDoc的type中嵌入import,它会作为补全选项给出。
代码如下。
//@ts-check
const mongo = require('mongodb')
class User {
constructor() {
/** @type {string} */
this.name = undefined;
}
}
const client = new mongo.MongoClient("");
/** @type {import("mongodb").FilterQuery<User>} */
const query = {
name: {
}
};
成功补全了

大致目标达成了,虽然有点麻烦。
问题所在
尽管在使补完更有效的意义上是成功的,但还是存在问题。
当尝试使用jsdoc命令生成JSDoc时,发生了错误。
ERROR: Unable to parse a tag's type expression for source file type.js in line 10 with tag title "type" and text "{import("mongodb").FilterQuery<User>}": Invalid type expression "import("mongodb").FilterQuery<User>": Expected "!", "=", "?", "[]", "|", or end of input but "(" found.
很遗憾,我没有预料到会有import出现在这里。
我还没有完全调查清楚,但能否通过设置或其他方式来避免呢?我对JSDoc并不太熟悉,如果有熟悉的人,请告诉我。
总结
我写了一篇关于如何辅助JavaScript进行类型补全的方法。
因为在认真编写代码时我已开始使用Typescript,所以并不是非常需要,但觉得还是有点需要,所以尝试了一些方法。
如果你主要是使用JavaScript的话,请试一试。如果有更好的方法,请告诉我。
请参考
在VS Code中进行Javascript类型判断 – Qiita
在Node.js(v8.5.0及以上版本)中使用import/export而不需要使用Babel或webpack – Qiita