我想在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> = {
}

这样做的话,在编辑查询内容时会像截图一样提供候选项。

alt

我想用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: {

    }
};

成功补全了

alt

大致目标达成了,虽然有点麻烦。

问题所在

尽管在使补完更有效的意义上是成功的,但还是存在问题。
当尝试使用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

bannerAds