【実務・中級編】 strictファミリーオプションの全容 – TypeScript実践ガイド

TypeScriptの「strict」は単なる縛りじゃない。お前を守る最強の鎧だ。

現場で「とりあえず `strict: true` にしてあるから大丈夫」なんて思っていないか?

正直に言おう。`tsconfig.json` の `strict: true` は、TypeScriptという言語が持つ「型安全性の最低ライン」だ。これを外すことは、高速道路を逆走しながら「ブレーキは踏まない主義だ」と豪語するのと同じくらい危険な行為なんだ。

今日は、中級エンジニアの君が「なぜこのフラグが必要なのか」「裏側で何が起きているのか」を腹落ちできるように、strictファミリーの深淵を紐解いていく。現場の荒波を乗り越えるための武器だと思って聞いてくれ。

—

なぜ「strict」を極める必要があるのか

ブラウザ(V8エンジンなど)は、実行時に「この変数は `null` かもしれない」なんて気を利かせてはくれない。JSのランタイムは、存在しないプロパティにアクセスした瞬間に静かに、しかし確実にクラッシュする。

TypeScriptの `strict` モードは、その「ランタイムの無慈悲なクラッシュ」を、開発中のエディタ上で「赤波線」として事前に可視化してくれる魔法なんだ。

1. `noImplicitAny`: 「なんとなく型」を撲滅する

これを `true` にすると、型推論が効かない場所で「型を指定しろ」とコンパイラが叫ぶようになる。

// noImplicitAny: false だと黙認されるが、これのせいで後でバグが爆発する
function calculate(x, y) {
return x + y;
}

// 修正後(strictの基本)
function calculate(x: number, y: number): number {
return x + y;
}

現場の教訓: `any` は逃げ道じゃない。「思考停止」のサインだ。`noImplicitAny` を切ることは、コードの可読性と保守性をドブに捨てることと同義だと心得ておけ。

2. `strictNullChecks`: ヌルポの恐怖からの解放

TypeScript界で最も重要なフラグだ。これが `false` だと、すべての型は自動的に `null` や `undefined` を許容してしまう。

// strictNullChecks: false の世界(悪夢)
const user = { name: “Alice” };
const name: string = user.nickname; // コンパイルは通るが、実行時にundefinedで死ぬ

// strictNullChecks: true の世界(現実)
interface User { name: string; nickname?: string }
const user: User = { name: “Alice” };

// コンパイルエラー: Object is possibly ‘undefined’.
// ここで初めて「あ、if文でチェックしなきゃ」と気づける
if (user.nickname) {
console.log(user.nickname.length);
}

ブラウザのメモリ上で、空っぽの箱にアクセスしようとしてエラーが起きる前に、コンパイラが「お前、それ中身入ってないかもよ?」と教えてくれる。これぞTypeScriptの真骨頂だ。

3. `strictFunctionTypes`: 関数の共変・反変を理解する

少し専門的な話になるが、これは「関数の引数の型が、期待する型より緩くてもいいのか?」という問題だ。

// strictFunctionTypes: true のおかげで防げる不整合
type Handler = (arg: string | number) => void;

// もしこれに (arg: string) => void を代入できたら?
// 実際には number が渡ってくる可能性があるのに、stringのメソッドしか使えない関数のせいでクラッシュする
const handler: Handler = (arg: string) => {
console.log(arg.toUpperCase()); // numberが来たらここで死ぬ
};

このフラグは、関数の代入可能性を厳しくチェックすることで、実行時の予期せぬ型エラーを未然に防いでくれる。

—

実務で意識すべき「黄金のtsconfig」

もし君が今、既存プロジェクトの `tsconfig.json` をいじっているなら、まずはここからスタートしてくれ。これが現代のフロントエンド開発における、最低限の「防衛ライン」だ。

{
“compilerOptions”: {
“strict”: true,
“noImplicitAny”: true,
“strictNullChecks”: true,
“strictFunctionTypes”: true,
“strictBindCallApply”: true,
“strictPropertyInitialization”: true,
“noImplicitThis”: true,
“alwaysStrict”: true
}
}

  • `strictBindCallApply`: `bind`, `call`, `apply` を使った時の引数の型チェックを厳格にする。これがないと、関数呼び出しがただの「型無視の実験場」になる。
  • `strictPropertyInitialization`: クラスのプロパティがコンストラクタで初期化されていない場合にエラーにする。ReactのClassコンポーネントや、複雑なクラス設計をする時に必須だ。

—

シニアからのアドバイス:厳しさは「愛」だ

「strictにするとコンパイルが通らなくて作業が進まない」と嘆くメンバーがいたら、こう伝えてやってくれ。

「そのエラーは、実行時にユーザーのブラウザで発生していたはずのクラッシュを、今ここで止めてくれたんだよ」と。

TypeScriptの型エラーは敵じゃない。リリース後に発生する「原因不明のバグ」という名の化け物を、事前に成敗してくれる味方なんだ。最初は面倒かもしれないが、型定義を整えることは、将来の自分やチームメンバーへの最大のギフトになる。

さあ、エディタを開いて `tsconfig.json` を確認しよう。その「赤波線」は、君がより良いエンジニアになるための証だ。何か困ったことがあれば、いつでもまた聞きに来てくれ。プロフェッショナルな現場で戦う仲間として、いつでも歓迎するぜ。

コメント

タイトルとURLをコピーしました