TypeScript や Flow ではなく JSDoc を用いた JavaScript のプロジェクトは多くありますが、特別なことをしない限り、 悲しいことに JSDoc を書いても、何も言ってくれません。
/** @type {Array} foo */
let foo = [];
foo = "foo"; // 何も言ってくれない...
console.log(foo); // foo
Visual Studio Code に置ける特別なことの選択肢の一つとして、TypeScript エンジンにチェックしてもらう方法があります。
ファイルの一番上に// @ts-check
を加えてみましょう。エラーを吐いてくれます。
// @ts-check
/** @type {Array} foo */
let foo = [];
foo = "foo"; // Error:型 '0' を型 'string' に割り当てることはできません。
console.log(foo);
また、それ以外の環境でも次のようにして確認することができます。
$ tsc --allowJs --checkJs --noEmit --target ES5 src/*.js
/**
* @type {string}
*/
const foo = "foo";
/** @type {string} */
/** @type {string|number} */
/** @type {string|number|undefined} */
/** @type {any} */
/** @type {Function} */
/**
* Set the title with the provided value.
* @param {string} newTitle
* @return {Node} H1 element.
*/
function setTitle(newTitle) {
return <h1>{newTitle}</h1>;
}
/** @type {Array<string>} */
/** @type {Array<string>} */
/** @type {string[]} */
const foo = ["foo", "bar"];
/** @type {Array<string|number>} */
const foo = ["foo", "bar", 0, 1];
/** @type {Array[]} */
const foo = [[], []];
/** @type {Object<string, string|number>} */
/** @type {Object.<string, string|number>} */
/** @type {{string, string|number}} */
/** @type {Object.<string, string|number>} */
const foo = { foo: "foo", bar: 2 };
/** @type {Object<string, Object<number, string>} */
const foo = { foo: { 1: "foo", 2: "foo" }, bar: { 3: "bar" } };
/** @type {{foo:string, bar:number}} */
const props = {
foo: "foo",
bar: 1
};
/**
* @typedef {Object<string, number>} Props
* @property {string} foo
* @property {number} bar
*/
/**
* @type {Props}
*/
/** @type Map.<string, any> */
/** @type Map<string, any> */
/** @type Set.<string> */
/** @type Set<string> */
/**
* Class to create a person object.
*/
class Person {
constructor(props) {
/**
* @property {string} name The person's name.
*/
this.name = props.name;
/**
* @property {number} age The person's name.
*/
this.age = props.age;
/**
* @property {Function} sayName A method to annouce the person's name.
* @returns void
*/
this.sayName = () => alert(this.name);
}
}
ライブラリの型定義を使いたい場合
/** @type {Map.<string, import("eslint").Rule.RuleModule>} */
const rules = engine.getRules();
自分で定義した d.ts ファイルを使いたい場合
foo.d.ts
export interface Foo {
foo: string;
bar: string | {} | number;
}
/** @type {import("../foo").Foo} */
自分で定義した JSDoc の記述を使いたい場合
foo.js
/**
* @typedef {string, string | {} | number} Foo
* @property {string} foo
* @property {string} bar
*/
/** @type {import("../foo").Foo} */
/** @type {{foo:string, bar:number, bar2?:number}} */
const props = {
foo: "foo",
bar: 1
};
/**
* @typedef {Object<string, number>} Props
* @property {string} foo
* @property {number} bar
* @property {number} [bar2]
*/
/**
* @type {Props}
*/
// Generic types may also be used
/**
* @template T
* @param {T} param - A generic parameter that flows through to the return type
* @return {T}
*/
function genericFnc(param) {
return param;
}
const btn = document.createElement("button");
/** @type {Element} */ (btn).setAttribute("disabled", "true");
VSCodeで@ propertyで書いた型の認識がおかしい場合があります。