読者です 読者をやめる 読者になる 読者になる

この日記は私的なものであり、所属会社の見解ではありません。 GitHub: takahashikzn

Google Closure Compilerのアノテーションで擬似キャスト

Javascript

jQuery.dataのように、どんな型の値が返ってくるか不確定なメソッドを使うとき、
たとえ自分が「必ずその型である」と確信が持てる状況であっても、それを通知する記法(キャスト記法)は用意されていません。


だから、

/** @type {!Array.<number>} */
var nums = $(".foobar").data("numValues");

のようなコードに対して、

initializing variable
found   : *
required: Array.<number>

と怒られることになります。

一旦、型なしにする

数値のようなビルトイン型の場合、

/** @type {!number} */
var num = +$(".foobar").data("numValue");

のようにして誤魔化せます *1 が、Array.<number>ではそれも不可能。

このようなケースでは即時関数を使って

/** @type {!Array.<number>} */
var num = (function() { return $(".foobar").data("numValues"); }());

とすることで誤魔化せますが、記述が美しくない。

"@type {?}"を使う

もっとマシな記法が無いか、皆様お馴染みのStackOverflowで探してみました。
で、こちらを見てピーンと来た。

http://stackoverflow.com/questions/10131118/google-closure-trouble-type-checking-parameters-that-should-be-functions


結論としては、

/** @type {!Array.<number>} */
var num = /** @type {?} */($(".foobar").data("numValues"));

でOKです。
パッと見にもキャストしたという意図がより伝わる(※当社比)し、即時関数よりはだいぶマシだと思います。


なお、キャスト対象となる式の全体をカッコで囲む必要があり、

/** @type {!Array.<number>} */
var num = /** @type {?} */ $(".foobar").data("numValues");

とか

/** @type {!Array.<number>} */
var num = (/** @type {?} */ $(".foobar").data("numValues"));

はダメな模様です。ご注意を。

*1:先頭の"+"により暗黙の型変換が発生