tsconfig.jsonのよく使いそうなオプションを理解する
tsconfig.jsonを書く時に必要なオプションが何だったか、どんな役割を持つかを忘れてしまうため、個人的によく使いそうなオプションを書いていきます。
TypeScriptのバージョンは4.4です。
各オプション
target
TypeScriptはJavaScriptにコンパイルされるため、その時にどのバージョンのJavaScriptで出力するかをtargetで指定します。
ドキュメントを確認すると、デフォルトはES3
ですが、以下の中からも選択できます。
es3, es5, es6/es2015, es2016, es2017, es2018, es2019, es2020, es2021, esnext
どれを選択すれば良いかは、Node.jsのバージョン毎に推奨されるtargetがあるため、node.greenを確認します。Node.jsのバージョンは、node -v
で確認できます。
Name | Supported Target | 利用可能なAPI(一部) |
---|---|---|
Node 8 | ES2017 | Object.entries、Object.values、date.formatToParts |
Node 10 | ES2018 | async iterables、promise.finally、rexexp.groups |
Node 12 | ES2019 | array.flat、array.flatMap、string.trimStart |
Node 14 | ES2020 | string.matchAll |
Node 16 | ES2021 | string.replaceAll |
tsconfig.jsonにtargetを指定する例
{
"compilerOptions": {
"target": "es2021"
}
}
lib
targetに指定しているjsのバージョンには含まれていない、組み込みライブラリを使用する場合は、libに明示的な指定が必要になります。(使用しない場合は、書かなくても問題ありません)
指定可能なライブラリの一例は下記のとおりです。
ES5, ES6, ES2015, ES7, ES2016, ES2017, DOM, DOM.Iterable, WebWorker, ScriptHost, ES2015.Core, ES2015.Collection, ES2015.Generator, ES2015.Iterable, ES2015.Promise, ES2015.Proxy, ES2015.Reflect, ES2015.Symbol, ES2015.Symbol.WellKnown, ES2016.Array.Include, ES2017.object, ES2017.SharedMemory
これらの情報はTypeScript source codeで最新版を確認できます。
tsconfig.jsonにlibを指定する例
{
"compilerOptions": {
"target": "es2021",
"lib": [
"es2021",
"esnext.promise",
"esnext.weakref"
]
}
}
module
出力されるJavaScriptが、どのようにモジュールを読み込むか指定します。バックエンドならcommonjs
、フロントエンドならes2021
やesnext
を指定すると良さそうです。
rootDir
コンパイル結果を出力する際に、どのディレクトリ配下を対象として出力するかを指定します。後述するincludeとは違い、コンパイル対象を決めるオプションではありません。
例えば設定を"rootDir": "./src"
として、
{
"compilerOptions": {
"rootDir": "./src"
}
}
ディレクトリの階層が以下のような時
├── src
│ └── hoge.ts
├── fuga.ts
└── tsconfig.json
hogeはsrc配下のため問題ないですが、fugaはsrc配下ではないためエラーとなります。
import hoge from './hoge'
import fuga from '../fuga'
moduleResolution
モジュールをどのように解決するのかを指定します。
指定する値は、NodeかClassicです。
以下のドキュメントを見ると、「かつてはTypeScriptのデフォルトの解決方法でした。現在では、この戦略は主に後方互換性のために存在しています」と書いてあるため、基本的にはnode
を指定すれば間違いないです。
resolveJsonModule
trueを指定することで、JSONファイルから型の抽出や生成を行います。
sourceMap
trueを指定することで、出力されたJavaScriptファイルが実際に動作させるとき、デバッガーが元のTypeScriptソースファイルを表示できるようします。
outDir
以下のtsconfigの設定でyarn tsc
を実行すると、出力されたJavaScriptファイルは、distフォルダに生成されます。
tsconfig.jsonにoutDirを指定する例
{
"compilerOptions": {
"outDir": "./dist"
}
}
yarn tscの実行
❯ yarn tsc
yarn run v1.22.11
$ /Users/hoge/test-project/node_modules/.bin/tsc
✨ Done in 3.42s.
treeコマンドでファイルの階層を確認する(例)
❯ tree dist
dist
├── index.js
└── index.js.map
importsNotUsedAsValues
importsNotUsedAsValues: "error"
interfaceなど型の定義だけを持つのファイルのインポートは、import type
でインポートしないと、コンパイルエラーにします。
// エラーになる
import { Ihoge } from "./Ihoge";
// エラーにならない
import type { Ihoge } from "./Ihoge";
forceConsistentCasingInFileNames
ファイルの文字列の大文字小文字を区別するかどうかを指定します。OSによっては、大文字小文字を区別出来ない場合があるため、trueにしておくと良さそうです。
ファイルが ./FileManager.ts を指定して fileManager.ts をインポートしようとした場合、ファイルは大文字と小文字を区別しないファイルシステムでは見つかりますが、大文字と小文字を区別するファイルシステムでは見つかりません。
strict
strictをtrueにすると、以下の各オプションがすべてtrueになります。デフォルト値はすべてfalseのため、trueにした場合の挙動は次のとおりです。
オプション | 説明 |
---|---|
alwaysStrict | strict modeで解釈し、出力されるJavaScriptファイルにもuse strictを追加する |
strictNullChecks | nullやundefinedを代入したい場合、明示的に指定しないといけなくなる |
strictBindCallApply | 歴史的経緯により正しく型付けされていなかった、Functionのbind(),call(),apply()メソッドを厳格に型付けする |
strictFunctionTypes | 歴史的経緯により存在した、Function型の誤った型変換が許されなくなる |
strictPropertyInitialization | コンストラクタ内でundefinedが許されないプロパティが、全て代入されているかどうかチェックされる |
noImplicitAny | 型が推論不能のときにコンパイルエラーにする |
noImplicitThis | thisの型が推論不能のときコンパイルエラーにする |
useUnknownInCatchVariables | catchの例外変数のデフォルトの型がunknownになる |
noImplicitReturns
関数の戻り値がvoid以外のときにreturnを必須にします。
noFallthroughCasesInSwitch
switch文で、caseをbreakやreturnで終えていることを必須にします。
noUncheckedIndexedAccess
インデックス型や配列で宣言されたオブジェクトが持つプロパティへのアクセスを厳密に評価します。まず、noUncheckedIndexedAccessがfalseの場合は、以下のコードを書いてもエラーになりません。変数result
がundefinedで出力されます。
type Props = {
[key: string]: string
}
const run = (props: Props) => {
const result: string = props.mouse
console.log(result) // undefined
}
const animal: Props = {
cat: "Meow",
dog: "Bowwow"
}
run(animal)
noUncheckedIndexedAccessをtrueにすることで、Type 'string | undefined' is not assignable to type 'string'. Type 'undefined' is not assignable to type 'string'.(2322)
とエラーを出してくれます。
noImplicitOverride
スーパークラスのメソッドをオーバーライドする時、overrideを必須にします。
include
コンパイルする対象ファイルを記述します。
src/**/*
と指定した場合、src配下のファイル全て(ディレクトリのネストが深くなっても再帰的に全て)がコンパイル対象になります。
includeの指定にファイルの拡張子が含まれていない場合、デフォルトでは.ts
.tsx
.d.ts
、allowJsがtrueの場合は.js
.jsx
が含まれます。
tsconfig.jsonにincludeを指定する例(includeはcompilerOptionsと同じく、1つめの階層で宣言します)
{
"compilerOptions": {
// 省略
},
"include": ["src/**/*"]
}
完成形
Node.jsのプロジェクトで使いたかったため、今回は"module": "commonjs",
を指定しています。
{
"compilerOptions": {
"target": "es2021",
"module": "commonjs",
"rootDir": "./src",
"moduleResolution": "node",
"resolveJsonModule": true,
"sourceMap": true,
"outDir": "./dist",
"importsNotUsedAsValues": "error",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
"noPropertyAccessFromIndexSignature": true
},
"include": ["src/**/*"]
}
所感
TypeScript: TSConfig ReferenceのType Checkingにある項目は、よく利用するので特に目を通しておいた方が良いです。
ドキュメントから引用すると、以下のオプションたちです。
allowUnreachableCode,allowUnusedLabels,alwaysStrict,exactOptionalPropertyTypes,noFallthroughCasesInSwitch,noImplicitAny,noImplicitOverride,noImplicitReturns,noImplicitThis,noPropertyAccessFromIndexSignature,noUncheckedIndexedAccess,noUnusedLocals,noUnusedParameters,strict,strictBindCallApply,strictFunctionTypes,strictNullChecks,strictPropertyInitialization anduseUnknownInCatchVariables
参考
Discussion