おい、調子はどうだい?
最近、TypeScriptが天下を取ったような顔をしているけれど、僕らの足元であるプレーンなJavaScriptの現場でも、型安全への欲求は日増しに高まっているよね。大規模なコードベースを複数人で触っていると、「おっと、この引数、`null`が入るなんて聞いてないぞ!」とか「なんでここで`undefined is not a function`の爆弾を踏むんだ……」という絶望を、一度や二度じゃなく味わってきたはずだ。
TypeScriptを導入できればベストだけど、様々な事情でJSDoc(JavaScript Documentation)を頼りにバリバリ型チェックを回しているプロジェクトもまだまだ多い。JSDocは単なる「コメントの毛が生えたもの」と侮るなかれ。VS CodeのTypeScript言語サービスと組み合わせれば、JSDocは立派な静的型検査の要塞に化けるんだ。
今回は、そのJSDocにおけるNull許容型(Nullable)と非Null型(Non-nullable)の表現方法について、裏側の挙動や実務で即座に使えるテクニックを交えて徹底的に解説しよう。
—
1. なぜJSDocの「Null許容・非Null」にこだわる必要があるのか?
JavaScriptは、良くも悪くも「寛容」な言語だ。変数を作って初期化をサボれば勝手に`undefined`が入り、DOM要素の取得に失敗すれば平然と`null`を返す。ブラウザのエンジン(V8など)は「お、空っぽの値だな。よし、そのまま処理を進めるぜ」と動くけれど、僕らフロントエンドエンジニアの脳内では「ここは絶対に値が入っていてほしい(非Null)」のか、「空っぽかもしれないからガードしなきゃいけない(Null許容)」のかの境界線が明確じゃないと、コードはすぐに破綻する。
JSDocを使う最大の理由は、コンパイルステップを通さないJavaScriptでありながら、エディタの入力補完や静的解析(`// @ts-check`)によって、実行時エラーを未然に潰すことにある。
ここで重要になるのが、Google Closure Compilerのスタイルに由来する、型名の前につけるプレフィックスだ。
- `?` (クエスチョンマーク):Null許容(Nullable)
- `!` (エクスクラメーションマーク):非Null(Non-nullable)
この記号の使い分けをマスターするだけで、君の書くJSDocの精度はプロフェッショナルなレベルに跳ね上がる。
—
2. 記法の基本:`?` と `!` の正体
JSDocの仕様において、実はデフォルトの挙動はプロジェクトのモードや設定によって揺らぐことがある。だからこそ、明示的に記号を付与することがシニアとしての作法になる。
Null許容型:`?` の使い方
型名の前に `?` を付けると、「この変数は、指定された型、もしくは `null` や `undefined` のどちらも受け入れますよ」という意味になる。
/
- ユーザーのプロフィールを表示する
- @param {?string} bio – 自己紹介文(nullやundefined、文字列を許容)
/
function renderBio(bio) {
// bioがnullやundefinedの可能性があるので、ガード節が必須になる
if (!bio) {
return ‘自己紹介は未設定です。’;
}
return `自己紹介: ${bio}`;
}
非Null型:`!` の使い方
型名の前に `!` を付けると、「ここには絶対に `null` も `undefined` も入らせない。入り込んだら型エラーだ!」とエディタに誓わせる宣言になる。
/
- 注文の合計金額を計算する
- @param {!number} price – 単価(絶対に数値でなければならない)
- @param {!number} quantity – 数量(絶対に数値でなければならない)
- @returns {!number} 合計金額
/
function calculateTotal(price, quantity) {
return price quantity;
}
—
3. 実務で遭遇する「DOM要素の取得」におけるベストプラクティス
現場で一番頭を悩ませるのが、`document.getElementById` や `querySelector` の戻り値だ。要素が存在すれば `HTMLElement` が返るし、存在しなければ容赦なく `null` が返ってくる。
ここで非Null型をどう活かすか、実際のコードを見てみよう。
// @ts-check
/
- モーダル要素を制御するクラス
/
class ModalController {
constructor() {
/
- モーダルのルート要素
- @private
- @type {?HTMLElement}
/
this.modalElement = document.querySelector(‘#app-modal’);
}
/
- モーダルを開く
/
open() {
// this.modalElement は ?HTMLElement なので、
// そのまま .style にアクセスするとエディタが怒る(あるいは警告が出る)
if (!this.modalElement) {
console.warn(‘モーダル要素がDOM上に存在しません。’);
return;
}
// ここに到達した時点で、TypeScriptのフロー解析により
// this.modalElement は HTMLElement(非Null)に絞り込まれている!
this.modalElement.style.display = ‘block’;
}
}
この「型ガード(Type Guard)」による型の絞り込み(Narrowing)は、裏側の言語サービスがスマートに処理してくれている。JSDocで `?HTMLElement` と正しく定義しておけば、`if (!this.modalElement)` を抜けた先のブロックでは、コンパイラはそれを非Nullとして扱ってくれるんだ。この連携技がたまらない。
—
4. チーム開発で失敗しないための実践Tips
最後に、僕がいくつもの現場を渡り歩いて得た、JSDocのNull許容型にまつわるリアルな教訓をいくつかシェアしておこう。
1. デフォルトの挙動を過信しない
プロジェクトの `jsconfig.json` や `tsconfig.json` の設定(`strictNullChecks` など)によって、記号をつけない場合のデフォルト挙動が変わる。余計なバグや誤解を生む温床になるので、曖昧にせず、「Nullを許容するなら `?`」「絶対に許容しないなら `!`」を明示的に書く習慣をチーム全体で徹底しよう。
2. オブジェクトのプロパティにも容赦なくつける
関数だけでなく、オブジェクトの構造定義(`@typedef`)でも威力を発揮する。
/
- @typedef {Object} UserSettings
- @property {!string} theme – テーマ(’light’ または ‘dark’)
- @property {?string} customAccentColor – カスタムカラー(未設定ならnull)
/
こう書いておけば、APIから返ってきたデータをアサインする時や、設定画面でバリデーションを書くときに、どのプロパティを警戒すべきかが一目瞭然になる。
—
まとめ
JSDocの `?` と `!` は、単なるコメントの装飾じゃない。それは、「このコードの意図はこうだ!」という君から次のメンテナ(あるいは未来の自分)への強力なメッセージであり、エディタを相棒にするための呪文だ。
JavaScriptの自由度の高さを愛しつつも、実務で絶対に落としたくない堅牢性を担保するために、今日のコーディングからこの記法をガンガン取り入れてみてほしい。コードの質が一段階グッと引き締まるのを実感できるはずさ。
それじゃ、また現場のコードレビューで会おう!

コメント