strict モードとは何か
TypeScript の strict モードは、一言でいうと「型チェックを最大限きびしくするスイッチ」です。tsconfig.json の compilerOptions に "strict": true と書くことで有効になり、複数の厳格な型チェックオプションがまとめてオンになります。これによって、「本当はバグだけど JavaScript 的には一応動いてしまうコード」を、コンパイル時点でどんどんエラーとしてあぶり出してくれるようになります。
公式の説明でも、strict フラグは「より強い正しさの保証を与えるための広範な型チェックを有効にする」とされています。つまり、「ちょっとゆるい TypeScript」から「本気でバグを減らしにいく TypeScript」にギアを上げるためのモードが strict だと考えるとイメージしやすいです。
strict モードがオンになると何が起きるか
いくつもの「厳しめオプション」が一括で有効になる
strict を true にすると、内部的には noImplicitAny や strictNullChecks をはじめとする複数のオプションがまとめて有効になります。これらはそれぞれ単体でも型安全性を高める設定ですが、strict をオンにすることで「全部まとめてオンにする」ことができます。
たとえば noImplicitAny は「暗黙の any を禁止する」オプションで、引数や変数の型を省略してしまったときに、自動的に any とみなされるのを許さなくなります。strictNullChecks は「null や undefined の扱いを厳しくする」オプションで、非 null 型の変数に null を代入したり、null かもしれない値にそのままメソッドを呼んだりするとコンパイルエラーになります。
これらが全部オンになることで、「なんとなく動いているけど実は危ない」コードが一気に表面化します。最初はエラーが増えてつらく感じるかもしれませんが、それは「潜在的なバグが見えるようになった」ということでもあります。
具体例で感じる strict モードの効果
noImplicitAny で「型を書き忘れ」をあぶり出す
まずは noImplicitAny の効果を、シンプルな例で見てみます。strict がオフのとき、次のようなコードは一応コンパイルできます。
// strict: false のイメージ
export const add = (value) => {
return value + 1;
};
TypeScriptこの場合、value の型は暗黙的に any とみなされます。つまり、「何が来てもいいよ」という超ゆるい型になってしまい、文字列を渡しても、数値を渡しても、コンパイラは何も言いません。
strict を true(= noImplicitAny も true)にすると、このコードはコンパイルエラーになります。TypeScript が「value の型が暗黙に any になっているよ。ちゃんと型を書いて」と教えてくれるわけです。
// strict: true のイメージ
export const add = (value: number): number => {
return value + 1;
};
TypeScriptこうして型を明示することで、「この関数は数値を受け取って数値を返す」という契約がはっきりし、間違った使い方をしたときにコンパイル時点で止められるようになります。
strictNullChecks で「null 由来のクラッシュ」を防ぐ
次に、strictNullChecks の効果を見てみます。strictNullChecks がオフのとき、TypeScript は null や undefined の代入をかなりゆるく許してしまいます。
// strictNullChecks: false のイメージ
const date: Date = null; // OK とみなされる
const error: Error = undefined; // これも OK とみなされる
TypeScriptしかし、実行時に date.getDay() のようなメソッドを呼ぶと、「Cannot read properties of null」といったエラーで落ちてしまいます。つまり、「コンパイルは通るけど、実行時にクラッシュする危険なコード」が紛れ込んでしまうわけです。
strict モード(= strictNullChecks: true)では、こうした代入はコンパイルエラーになります。
// strictNullChecks: true のイメージ
const date: Date = null; // コンパイルエラー
const error: Error = undefined; // これもコンパイルエラー
TypeScriptTypeScript が「Date 型の変数に null は代入できないよ」と教えてくれるので、「null かもしれない値」は型としても Date | null のように表現し、使う前に必ずチェックする、というスタイルに自然と誘導されます。これが、null 由来のクラッシュを大幅に減らしてくれるポイントです。
strict モードが「すごい」と言われる理由
潜在的なバグを「実行前」に潰せる
strict モードの本質的な価値は、「潜在的なバグをコンパイル時点で潰せる」ことです。たとえば、次のような関数を考えてみます。
// strict: false のイメージ
function greet(name) {
return "Hello, " + name.toUpperCase();
}
TypeScriptここでは name の型が暗黙に any になっていて、コンパイルは通ります。しかし、実行時に greet(null) のような呼び出しが来ると、name.toUpperCase() のところでクラッシュします。
strict モードでは、まず name に型を付けることが求められます。
// strict: true のイメージ
function greet(name: string) {
return "Hello, " + name.toUpperCase();
}
TypeScriptこうしておけば、「この関数は string しか受け取らない」という契約が明確になり、greet(null) のような呼び出しはコンパイル時点でエラーになります。つまり、「実行してから気づくバグ」を「書いている段階で気づけるバグ」に変えてくれるのが strict モードです。
初心者が strict モードをどう捉えるべきか
「うるさいけど、めちゃくちゃ面倒見のいい先生」
strict をオンにすると、最初はエラーが一気に増えて「なんでこんなに怒られるんだ…」と感じるかもしれません。でも、そのエラーはすべて、「将来あなたがハマるはずだったバグのタネ」です。TypeScript 公式も、strict 系のオプションを有効にすることで、より強い正しさの保証が得られるとしています。
特に、noImplicitAny や strictNullChecks のようなオプションは、暗黙の any や null 由来のクラッシュといった、現場でよくある事故をかなりの確率で防いでくれます。初心者ほど、型の書き忘れや null の扱いミスが起きやすいので、strict モードはむしろ「初心者の味方」だと考えていいです。
最初は、エラーの意味をひとつずつ読み解きながら、「なぜこれは危ないのか」「どう書き直せば安全なのか」を理解していくことが大事です。strict モードは、あなたのコードに対して常にフィードバックをくれる、かなり優秀なレビュー担当だと思って付き合うと、学びのスピードも、コードの質も一気に上がっていきます。
