メインコンテンツまでスキップ

isolatedModules

isolatedModulesは、各ファイルを独立して変換する際に、解釈できないコードがある場合に警告するコンパイラオプションです。

  • デフォルト: false
  • 追加されたバージョン: 1.5

isolatedModulesはトランスパイラ向けのオプション

TypeScriptをJavaScriptに変換する際、複数のファイルが関連することがあります。しかし、Babelのようなトランスパイラは、1ファイルずつ処理するため、一部コードが正しく解釈されないことがあります。

具体的には、const enumnamespaceなどの機能を使用すると、実行時に問題が発生することがあります。isolatedModulesは、このような問題を回避するために、正しく解釈できないコードがある場合に警告します。

isolatedModulesが有効な場合に機能しないコード

以下は、isolatedModulesが有効な場合に機能しないコードの例です。

値でない識別子のエクスポート

TypeScriptでは、インポートした型を再エクスポートすることができます。
これは、複数のモジュールから型や関数をまとめてエクスポートする際に便利です。ただし、isolatedModulesが有効な場合、型を再エクスポートする際にexport typeを使わないとエラーが発生します。

問題のあるコード:

someModule.ts
ts
export type SomeType = any;
export function hello() {
console.log("hello");
}
someModule.ts
ts
export type SomeType = any;
export function hello() {
console.log("hello");
}
index.ts
ts
import { SomeType, hello } from "./someModule";
 
// someTypeは値?それとも型?トランスパイラには判断できない
export { SomeType, hello };
Re-exporting a type when the '--isolatedModules' flag is provided requires using 'export type'.
index.ts
ts
import { SomeType, hello } from "./someModule";
 
// someTypeは値?それとも型?トランスパイラには判断できない
export { SomeType, hello };
Re-exporting a type when the '--isolatedModules' flag is provided requires using 'export type'.

解決策:

export typeを使用して型を再エクスポートすることで、エラーを回避できます。

index.ts
ts
import { SomeType, hello } from "./someModule";
 
export type { SomeType }; // 型だと判定できる
export { hello };
index.ts
ts
import { SomeType, hello } from "./someModule";
 
export type { SomeType }; // 型だと判定できる
export { hello };

モジュールでないファイル

isolatedModules が設定されている場合、すべての実装ファイルは モジュールでなければなりません。モジュールとは、importexportの構文を使用していることを意味します。ファイルがモジュールでない場合、エラーが発生します。

問題のあるコード:

index.ts
ts
function fn() {}
'index.ts' cannot be compiled under '--isolatedModules' because it is considered a global script file. Add an import, export, or an empty 'export {}' statement to make it a module.
index.ts
ts
function fn() {}
'index.ts' cannot be compiled under '--isolatedModules' because it is considered a global script file. Add an import, export, or an empty 'export {}' statement to make it a module.

解決策:

ファイルをモジュール化するために、空のexport {}文を追加します。

index.ts
ts
function fn() {}
 
// 空の export文を追加することでモジュール化する
export {};
index.ts
ts
function fn() {}
 
// 空の export文を追加することでモジュール化する
export {};

const enum メンバーへの参照

TypeScriptでは、const enumのメンバーに参照すると、生成されるJavaScriptではその参照が実際の値に置き換えられます。しかし、他のトランスパイラは、メンバー値に関する情報がないため、参照を置き換えることができません。そのため、実行時にエラーが発生します。

問題のあるコード:

index.ts
ts
declare const enum Numbers {
Zero = 0,
One = 1,
}
 
console.log(Numbers.Zero + Numbers.One);
Cannot access ambient const enums when the '--isolatedModules' flag is provided.
index.ts
ts
declare const enum Numbers {
Zero = 0,
One = 1,
}
 
console.log(Numbers.Zero + Numbers.One);
Cannot access ambient const enums when the '--isolatedModules' flag is provided.

解決策:

const enumの代わりに、通常のenumを使用することで、エラーを回避できます。

numbers.ts
ts
enum Numbers {
Zero = 0,
One = 1,
}
 
// 通常の enum への参照は許可されます
console.log(Numbers.Zero + Numbers.One);
numbers.ts
ts
enum Numbers {
Zero = 0,
One = 1,
}
 
// 通常の enum への参照は許可されます
console.log(Numbers.Zero + Numbers.One);

isolatedModulesは、このような問題を回避するためのコンパイラオプションです。
警告を出してくれることにより、コンパイラが正しく解釈できないコードの存在に気がつくことができます。

create-react-appcreate-next-appで生成されたtsconfig.jsonのisolatedModulesをfalseにしてはいけない

ReactやNext.jsの雛形生成ツールによって作成されたtsconfig.jsonでは、isolatedModulesが有効化されています。これは、ReactやNextが内部でBabelを使用しているためです。isolatedModulesをfalseに変えてしまうとビルドできなくなる可能性があるため、設定を変更しないようにしましょう。

学びをシェアする

✅isolatedModulesはファイル単位での変換を前提に解釈できないコードをチェックする
🚧Babelなどのトランスパイラとの互換性向上のために存在する
👍isolatedModulesは有効にしよう

『サバイバルTypeScript』より

この内容をツイートする