以下のリストは、JavaScriptファイルの型情報を提供する JSDocアノテーションにおいて、現在サポートされている構文の概要です。
以下に明示的にリストに入っていないタグ(@asyncなど)はまだサポートされていないことに注意してください。
@type@param(or@argor@argument)@returns(or@return)@typedef@callback@template@class(or@constructor)@this@extends(or@augments)@enum
class拡張
- プロパティ修飾子
@public、@private、@protected、@readonly
タグの意味は通常、jsdoc.appで与えられたものと同じか、あるいはそのスーパーセットです。 以下のコードでは、それぞれのタグの違いを説明し、使用例を示します。
注意: JSDocサポートを探るプレイグラウンドを使用できます
@type
“@type”タグを使用すれば、型名(プリミティブ、TypeScript宣言やJSDocの”@typedef”タグで定義されたもの)を参照することができます。
ほとんどのJSDoc型と、stringのような最も基本的なものからConditional Typesのような高度なものまで、あらゆるTypeScriptの型を使うことができます。
jsTry/*** @type {string}*/vars ;/** @type {Window} */varwin ;/** @type {PromiseLike<string>} */varpromisedString ;// DOMプロパティを使ってHTML要素を指定することができます。/** @type {HTMLElement} */varmyElement =document .querySelector (selector );element .dataset .myData = "";
@typeではUnion型も指定できます — 例えば、次の型は文字列か真偽値のどちらかになります。
jsTry/*** @type {(string | boolean)}*/varsb ;
Union型の場合は、丸括弧は任意であることに注意してください。
jsTry/*** @type {string | boolean}*/varsb ;
様々な構文を使って配列の型を指定することができます:
jsTry/** @type {number[]} */varns ;/** @type {Array.<number>} */varnds ;/** @type {Array<number>} */varnas ;
オブジェクトリテラル型を指定することもできます。 例えば、‘a’ (文字列) と ‘b’ (数値) をプロパティとして持つオブジェクトは次のような構文を使って指定します:
jsTry/** @type {{ a: string, b: number }} */varvar9 ;
JSDocの標準構文かTypeScriptの構文を使えば、文字列と数値のインデックスシグネチャを使ってマップや配列のようなオブジェクトを指定することができます。
jsTry/*** 任意の`string`プロパティを`number`にマッピングするマップライクなオブジェクト** @type {Object.<string, number>}*/varstringToNumber ;/** @type {Object.<number, object>} */vararrayLike ;
前述の2つの型は、TypeScriptの型である{ [x: string]: number }および{ [x: number]: any }と等価です。コンパイラは両方の構文を理解します。
関数は、TypeScriptとClosureのどちらの構文を使っても指定することができます:
jsTry/** @type {function(string, boolean): number} Closure構文 */varsbn ;/** @type {(s: string, b: boolean) => number} TypeScript構文 */varsbn2 ;
あるいは、型が特定されていないFunction型を使うこともできます:
jsTry/** @type {Function} */varfn7 ;/** @type {function} */varfn6 ;
Closureの他の型でも動作します:
jsTry/*** @type {*} - 'any'型になります*/varstar ;/*** @type {?} - 不明な型('any'と同じ)*/varquestion ;
キャスト
TypeScriptはClosureからキャスト構文を借用しています。
これにより、丸括弧で囲まれた式の前に@typeタグを追加することで、型を他の型にキャストすることができます。
jsTry/*** @type {number | string}*/varnumberOrString =Math .random () < 0.5 ? "hello" : 100;vartypeAssertedNumber = /** @type {number} */ (numberOrString );
インポート型
インポート型を使用して他のファイルから宣言をインポートすることもできます。 この構文はTypeScript固有のものであり、JSDocの標準とは異なります:
jsTry// @filename: types.d.tsexport typePet = {name : string,};// @filename: main.js/*** @param p { import("./types").Pet }*/functionwalk (p ) {console .log (`Walking ${p .name }...`);}
インポート型は型エイリアス宣言でも使用できます:
jsTry/*** @typedef { import("./types").Pet } Pet*//*** @type {Pet}*/varmyPet ;myPet .name ;
型がわからない場合や型が大きくて型を付けるのが面倒な場合に、インポート型を使ってモジュールから値の型を取得することができます:
jsTry/*** @type {typeof import("./accounts").userAccount }*/varx =require ("./accounts").userAccount ;
@paramと@returns
@paramは@typeと同じ型の構文を使用しますが、パラメータ名を追加します。
また、パラメータ名を角括弧で囲むことで、パラメータを任意のものとして宣言することもできます:
jsTry// パラメータは様々な構文形式で宣言することができます/*** @param {string} p1 - 文字列パラメータ* @param {string=} p2 - 任意のパラメータ(Closure構文)* @param {string} [p3] - 任意のパラメータ(JSDoc構文).* @param {string} [p4="test"] - デフォルト値を持つ任意のパラメータ* @return {string} 結果*/functionstringsStringStrings (p1 ,p2 ,p3 ,p4 ) {// TODO}
関数の戻り値の型についても同様です:
jsTry/*** @return {PromiseLike<string>}*/functionps () {}/*** @returns {{ a: string, b: number }} - '@returns'と同じく'@return'を使うことができます*/functionab () {}
@typedef、@callbackおよび@param
複雑な型を定義するために@typedefを使うことができます。
@paramを使った同様の構文でも動作します。
jsTry/*** @typedef {Object} SpecialType - 'SpecialType'という名前の新しい型を作成* @property {string} prop1 - SpecialTypeの文字列プロパティ* @property {number} prop2 - SpecialTypeの数値プロパティ* @property {number=} prop3 - SpecialTypeの任意の数値プロパティ* @prop {number} [prop4] - SpecialTypeの任意の数値プロパティ* @prop {number} [prop5=42] - SpecialTypeのデフォルト値を持つ任意の数値プロパティ*//** @type {SpecialType} */varspecialTypeObject ;specialTypeObject .prop3 ;
最初の行には、objectあるいはObjectのどちらかを使うことができます。
jsTry/*** @typedef {object} SpecialType1 - 'SpecialType'という名前の新しい型を作成* @property {string} prop1 - SpecialTypeの文字列プロパティ* @property {number} prop2 - SpecialTypeの数値プロパティ* @property {number=} prop3 - SpecialTypeの任意の数値プロパティ*//** @type {SpecialType1} */varspecialTypeObject1 ;
@paramを使えば、同様の構文で一回限りの型を指定することができます。
ネストされたプロパティ名の前には、パラメータ名をつけなければならないことに注意してください:
jsTry/*** @param {Object} options - 形状は上記のSpecialTypeと同じ* @param {string} options.prop1* @param {number} options.prop2* @param {number=} options.prop3* @param {number} [options.prop4]* @param {number} [options.prop5=42]*/functionspecial (options ) {return (options .prop4 || 1001) +options .prop5 ;}
@callbackは@typedefに似ていますが、オブジェクト型ではなく関数型を指定します:
jsTry/*** @callback Predicate* @param {string} data* @param {number} [index]* @returns {boolean}*//** @type {Predicate} */constok = (s ) => !(s .length % 2);
もちろん、これらの型はすべてTypeScriptの構文を使って一行の@typedefで宣言することができます:
js/** @typedef {{ prop1: string, prop2: string, prop3?: number }} SpecialType *//** @typedef {(data: string, index?: number) => boolean} Predicate */
@template
ジェネリクス関数は@templateタグを使って宣言することができます:
jsTry/*** @template T* @param {T} x - 戻り値に流用するジェネリクスパラメータ* @return {T}*/functionid (x ) {returnx ;}consta =id ("string");constb =id (123);constc =id ({});
複数の型パラメータを宣言するには、コンマか複数のタグを使用します:
js/*** @template T,U,V* @template W,X*/
型パラメータ名の前に、型制約を指定することもできます。 リストにある最初の型パラメータだけが、制約を受けます:
jsTry/*** @template {string} K - Kは文字列または文字列リテラルでなければなりません* @template {{ serious(): string }} Seriousalizable - seriousメソッドを持っていなければなりません* @param {K} key* @param {Seriousalizable} object*/functionseriousalize (key ,object ) {// ????}
ジェネリクスのクラスや型の宣言はサポートされていません。
クラス
クラスはES6のクラスとして宣言することができます。
jsTryclassC {/*** @param {number} data*/constructor(data ) {// プロパティの型は推測されますthis.name = "foo";// あるいは、明示的に設定することもできます/** @type {string | null} */this.title = null;// また、他のところで設定されている場合は、単に型注釈をつけることもできます/** @type {number} */this.size ;this.initialize (data ); // initializerは文字列を受け取るので、エラーになるべきです}/*** @param {string} s*/initialize = function (s ) {this.size =s .length ;};}varc = newC (0);// Cはnewを使用した場合のみ呼び出されるべきですが、// JavaScriptでは、以下は許可されており、// これは'any'型とみなされます。varresult =C (1);
次の節で説明するように、コンストラクタ関数として宣言することもできます:
@constructor
コンパイラはthisプロパティの代入に基づいてコンストラクタ関数を推測しますが、@constructorタグを追加すればより厳密なチェックとより良い提案を受けることができます:
jsTry/*** @constructor* @param {number} data*/functionC (data ) {// プロパティの型は推測されますthis.name = "foo";// あるいは、明示的に設定することもできます/** @type {string | null} */this.title = null;// また、他のところで設定されている場合は、単に型注釈をつけることもできます/** @type {number} */this.size ;this.Argument of type 'number' is not assignable to parameter of type 'string'.2345Argument of type 'number' is not assignable to parameter of type 'string'.initialize (); data }/*** @param {string} s*/C .prototype .initialize = function (s ) {this.size =s .length ;};varc = newC (0);c .size ;varValue of type 'typeof C' is not callable. Did you mean to include 'new'?2348Value of type 'typeof C' is not callable. Did you mean to include 'new'?result =C (1);
@constructorでは、thisはコンストラクタ関数Cの内部でチェックされるので、数値を渡すとinitializeメソッドへの提案とエラーが表示されます。また、コンストラクタの代わりにCを呼び出すと、エディタが警告を表示することもあります。
残念ながら、これは呼び出しも可能なコンストラクタ関数では、@constructorを使用できないことを意味します。
@this
コンパイラは通常、thisが用いられるコンテクストからthisの型を推測することができます。推測できない場合、@thisを使って明示的にthisの型を指定することができます:
jsTry/*** @this {HTMLElement}* @param {*} e*/functioncallbackForLater (e ) {this.clientHeight =parseInt (e ); // 大丈夫なはず!}
@extends
JavaScriptクラスがジェネリクスの基底クラスを拡張するとき、型パラメータが何であるべきかを指定するところがありません。@extendsタグはそのような型パラメータを指定する方法を提供しています:
jsTry/*** @template T* @extends {Set<T>}*/classSortableSet extendsSet {// ...}
@extendsは、クラスに対してのみ動作することに注意してください。現在、コンストラクタ関数がクラスを拡張する方法はありません。
@enum
@enumタグを使うと、すべてのメンバが指定された型であるオブジェクトリテラルを作成することができます。JavaScriptのたいていのオブジェクトリテラルとは異なり、明示されていないメンバは使用できません。
jsTry/** @enum {number} */constJSDocState = {BeginningOfLine : 0,SawAsterisk : 1,SavingComments : 2,};JSDocState .SawAsterisk ;
注意すべき点は、@enumはTypeScriptのenumとは大きく異なっており、とてもシンプルです。一方で、TypeScriptのenumとは違って、@enumは任意の型を持つことができます:
jsTry/** @enum {function(number): number} */constMathFuncs = {add1 : (n ) =>n + 1,id : (n ) => -n ,sub1 : (n ) =>n - 1,};MathFuncs .add1 ;
その他の例
jsTryvarsomeObj = {/*** @param {string} param1 - プロパティの割り当てに関する仕様は、*/x : function (param1 ) {},};/*** 変数の代入や* @return {Window}*/letsomeFunc = function () {};/*** クラスメソッド、* @param {string} greeting 使用する挨拶*/Foo .prototype .sayHi = (greeting ) =>console .log ("Hi!");/*** アロー関数式でも同様に動作します* @param {number} x - 乗数*/letmyArrow = (x ) =>x *x ;/*** つまり、JSXのステートレス関数コンポーネントでも動作するということです* @param {{a: string, b: number}} test - いくつかのパラメータ*/varsfc = (test ) => <div >{test .a .charAt (0)}</div >;/*** パラメータには、Closure構文を使用して、クラスのコンストラクタを使用することができます。** @param {{new(...args: any[]): object}} C - 登録するクラス*/functionregisterClass (C ) {}/*** @param {...string} p1 - 文字列の'レストパラメータ'(配列)引数 ('any'として扱われます)*/functionfn10 (p1 ) {}/*** @param {...string} p1 - 文字列の'レストパラメータ'(配列)引数 ('any'として扱われます)*/functionfn9 (p1 ) {returnp1 .join ();}
サポートされていないことが知られているパターン
コンストラクタ関数のようにオブジェクトも型を作らない限り、値空間のオブジェクトを型として参照することはできません。
jsTryfunctionaNormalFunction () {}/*** @type {aNormalFunction}*/varwrong ;/*** 'typeof'を代わりに使用します:* @type {typeof aNormalFunction}*/varright ;
オブジェクトリテラル型のプロパティ型の後ろに等号をつけても、任意のプロパティにはなりません:
jsTry/*** @type {{ a: string, b: number= }}*/varwrong ;/*** 代わりにプロパティ名の後ろにクエスチョンマークを付けます:* @type {{ a: string, b?: number }}*/varright ;
strictNullChecksが有効化されている場合のみ、Nullable型は動作します:
jsTry/*** @type {?number}* strictNullChecks: trueの場合 -- number | null* strictNullChecks: falseの場合 -- number*/varnullable ;
Union型も使うことができます:
jsTry/*** @type {number | null}* strictNullChecks: trueの場合 -- number | null* strictNullChecks: falseの場合 -- number*/varunionNullable ;
非Nullable型は意味を持たず、元の型と同じように扱われます:
jsTry/*** @type {!number}* 数値型だけをもちます*/varnormal ;
JSDocの型システムとは異なり、TypeScriptは型にnullが含まれるかどうか記すことしかできません。
明示的な非Nullable型はありません — strictNullChecksが有効なら、numberはNullableではありません。
無効なら、numberはNullableです。
サポートされていないタグ
TypeScriptはサポートされていないJSDocタグを無視します。
以下のタグは、サポートを目標とした進行中のIssueがあります:
@const(issue #19672)@inheritdoc(issue #23215)@memberof(issue #7237)@yields(issue #23857){@link …}(issue #35524)
JSクラスの拡張
JSDocプロパティ修飾子
TypeScript 3.8以降、JSDocを使ってクラスプロパティを修飾することができます。まずは、アクセシビリティ修飾子@public、@private、@protectedです。
これらのタグは、TypeScriptのpublic、private、protectedとそれぞれ同じように動作します。
jsTry// @ts-checkclassCar {constructor() {/** @private */this.identifier = 100;}printIdentifier () {console .log (this.identifier );}}constc = newCar ();Property 'identifier' is private and only accessible within class 'Car'.2341Property 'identifier' is private and only accessible within class 'Car'.console .log (c .); identifier
@publicは常に暗黙的に宣言されており、省略可能です。どこからでもプロパティにアクセスできることを意味します。@privateは、そのプロパティが含まれるクラス内でのみ使用可能であることを意味します。@protectedは、そのプロパティが含まれるクラスと、そのクラスの派生クラス内で使用可能ですが、クラスのインスタンスからはアクセスできません。
次に、@readonly修飾子を追加しました。これを使用すると、プロパティが初期化時にのみ書き込まれることが保証されます。
jsTry// @ts-checkclassCar {constructor() {/** @readonly */this.identifier = 100;}printIdentifier () {console .log (this.identifier );}}constc = newCar ();console .log (c .identifier );