JavaScript/TypeScript

tsconfig と strict を読む

6
  • 環境構築

tsconfig と strict を読む — TypeScript Tips

TypeScript の挙動は tsconfig.json がスイッチ です。特に strict は複数の厳格チェックをまとめて有効にします。学習・小規模 CLI 向けの最小構成と、主要オプションと strict の内訳です。

参考: TypeScript — tsconfig.json · TypeScript — strict · TypeScript — Compiler Options


目次

  1. tsconfig.json の役割
  2. ファイルの置き場所と include
  3. よく触る compilerOptions
  4. strict が有効にするもの
  5. 実用的な最小 tsconfig
  6. オプションと症状の対応表
  7. 詰まりやすい点

tsconfig.json の役割

tsc(TypeScript コンパイラ)とエディタの型チェックは、同じ tsconfig.json を参照します。プロジェクトルートに1つ置くのが基本です。

flowchart LR  TS["*.ts ソース"]  CFG["tsconfig.json"]  TSC["tsc / エディタ"]  TS --> TSC  CFG --> TSC
役割 説明
対象ファイルの範囲 include / exclude
出力形式 target, module, outDir
型の厳しさ strict および個別フラグ
モジュール解決 moduleResolution, paths など

「設定なしで TypeScript」は実質ありません。空のプロジェクトでも 意図した tsconfig を書く ことが出発点です。


ファイルの置き場所と include

{  "include": ["src"],  "exclude": ["node_modules", "dist"]}
  • include: 型チェック・コンパイル対象の glob
  • exclude: 除外(省略時も node_modules は大抵除外される)

src/index.ts だけを対象にするなら "include": ["src"] で足ります。テストを別フォルダに置くときは "include": ["src", "tests"] のように広げます。

ルートに tsconfig を置く理由

エディタは開いているファイルから上に辿って tsconfig.json を探します。サブフォルダだけに置くと、ルートのファイルがプロジェクト外扱いになることがあります。


よく触る compilerOptions

target

出力する JavaScript の言語レベルです。学習用なら ES2022 前後が無難です。

"target": "ES2022"

module と moduleResolution

Node で ES モジュール(import / export)を使うなら ペアで 揃えます。

"module": "NodeNext","moduleResolution": "NodeNext"

package.json"type": "module" がある前提です。従来の構成には CommonJS と旧式の node(現在の名称は node10)の組み合わせもありますが、新規の Node.js プロジェクトでは NodeNext を基本にします。

rootDir と outDir

"rootDir": "src","outDir": "dist"

ソースは src/、コンパイル結果は dist/ に出す、という整理です。型チェックだけ(noEmit: true)なら outDir は実行時には使いませんが、将来 tsc で吐き出すときのために書いておくとよいです。

noEmit

"noEmit": true

型チェックだけ行い、JS ファイルを生成しない 設定です。実行は tsxnode(コンパイル後)に任せる構成でよく使います。

skipLibCheck

"skipLibCheck": true

node_modules 内の .d.ts の型矛盾をスキップし、チェックを速くします。学習・小規模プロジェクトでは true で問題ないことが多いです。


strict が有効にするもの

"strict": true は次のオプションを まとめて true にするショートカットです。

フラグ ざっくりした意味
strictNullChecks null / undefined を型から区別
strictFunctionTypes 関数型の引数を厳密にチェック
strictBindCallApply bind / call / apply の型を厳密に
strictPropertyInitialization クラスプロパティの初期化を要求
noImplicitAny 暗黙の any を禁止
noImplicitThis this の型が曖昧ならエラー
alwaysStrict 出力 JS に "use strict"
useUnknownInCatchVariables catch した値を any ではなく unknown として扱う
strictBuiltinIteratorReturn 組み込みイテレータの完了時の戻り値型を厳密に扱う

初心者にいちばん効くのは strictNullChecksnoImplicitAny です。strict: true を付けておけば、これらも含まれます。TypeScript の更新で strict 配下のチェックが追加されることもあるため、バージョン更新時にはリリースノートも確認します。

strictNullChecks の例

function printLength(s: string) {  console.log(s.length);}const value: string | null = null;printLength(value); // エラー: null の可能性

strict なしだと null がそのまま渡せて、実行時に落ちる可能性があります。コンパイル時に止められるのが TypeScript の価値です。

noImplicitAny の例

function add(a, b) {  return a + b;}

引数に型がないと any 扱いになり、strict ではエラーになります。明示的に書きます。

function add(a: number, b: number): number {  return a + b;}

個別に緩めたいときは strict: true のまま "noImplicitAny": false のように 上書き できます。ただし学習段階では strict: true 一本で慣れる方が後々楽です。


実用的な最小 tsconfig

Node + TypeScript 学習用のコピペ例です。

{  "compilerOptions": {    "target": "ES2022",    "module": "NodeNext",    "moduleResolution": "NodeNext",    "strict": true,    "noEmit": true,    "skipLibCheck": true,    "rootDir": "src",    "outDir": "dist",    "esModuleInterop": true,    "forceConsistentCasingInFileNames": true  },  "include": ["src"]}
オプション この例での意図
strict 型の穴を減らす
noEmit tsc はチェック専用
esModuleInterop import fs from "fs" などが書きやすい
forceConsistentCasingInFileNames ファイル名の大文字小文字ミスを検出(Windows でも有効)

確認コマンド

npx tsc --noEmit

package.jsonscripts"typecheck": "tsc --noEmit" を入れておくと便利です。


オプションと症状の対応表

エラーや症状 関連しがちな設定
Object is possibly 'null' strictNullChecksstrict に含まれる)
引数に型がないとエラー noImplicitAny
import が解決できない module / moduleResolution、拡張子 .js の要否(NodeNext)
パスエイリアス @/ が効かない paths + baseUrl(別途設定が必要)
チェックが遅い skipLibCheck: true
JS が出力されない noEmit: true になっていないか確認
flowchart TB  subgraph strict_block["strict: true"]    SN["strictNullChecks"]    NA["noImplicitAny"]    Others["その他 strict* フラグ"]  end  CFG["tsconfig.json"] --> strict_block  CFG --> MOD["module / moduleResolution"]  CFG --> EMIT["noEmit / outDir"]

詰まりやすい点

症状 対処
エディタと tsc で結果が違う エディタが別の tsconfig を見ていないか。ワークスペースルートを開く
Cannot find module './foo' NodeNext では相対 import に拡張子が要る場合あり。./foo.js(出力後の名前)を指定
全部 any になっている checkJs// @ts-nocheck、暗黙 any。strict と明示的な型注釈を確認
strict を外したらエラーが消えた 一時しのぎにはなるが、実行時バグが増えやすい。該当箇所に正しい型を足す
サブフォルダだけ別設定にしたい tsconfig.build.jsonextends で継承
JSON のコメントでパースエラー tsconfig.json はコメント可。.json として厳密なツールには注意

extends で公式や社内のベースを継承するのも定番です。

{  "extends": "./tsconfig.base.json",  "compilerOptions": {    "outDir": "dist"  },  "include": ["src"]}

シェア