5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Visual Studio Codeで依存モジュールの型定義を使いたい(JavascriptのNode.jsで)

Last updated at Posted at 2019-07-25

本記事はcloudpack あら便利カレンダー 2019の記事です

タイトルが難しい。何をしたいのか伝えられた自信がない

以前 VS CodeでJavascriptの型判定を行う - Qiita という記事を書きました。

この記事では触れていなかったのですが、これどうやるんだろう?っていう内容がありました。

やりたいこと

  • 依存モジュールのtypeinterfaceで定義された情報をローカル変数の型に指定したい
  • 指定した型に基づいてVisual Studio Codeに補完してほしい
  • Node.jsで

mongoclient触っている時に思ったので、これを例にします

クエリを投げる時にどんなクエリが投げられるか忘れるので、型補完してほしい。
そのためにFilterQueryというtypeが用意されているのでJavascriptでもそれを利用したい。

// こんな感じで指定したら
/** @type {FilterQuery} */
const query = {
    // ここで色々補完してほしい
}

補完してみる

Typescriptなら簡単

普通にimportして型を指定すれば良いです。

import { FilterQuery, MongoClient } from "mongodb";


interface User {
    name: string
}

const client = new MongoClient("");
const query: FilterQuery<User> = {
}

こうしておけば、queryの中身を編集する際にキャプチャのように候補を出してくれます。

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 ***は見えないようにしている?

というわけで、requireでは無理でした。

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 {

動かすためには.mjsという拡張子にする必要があるようです。(Node.js(v8.5.0以降)で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以降)でBabelやwebpackを利用せずにimport/exportを利用する - Qiita

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?