Set.unknownの反復におけるES2015ターゲットとdownlevelIterationフラグ
問題概要
TypeScriptで配列から重複を削除するために [...new Set(array)]
構文を使用すると、次のエラーが発生します:
Type 'Set<unknown>' can only be iterated through when using the '--downlevelIteration' flag or with a '--target' of 'es2015' or higher
このエラーは、スプレッド構文とSetオブジェクトの組み合わせが、現在のTypeScriptターゲット設定ではサポートされていないことを示しています。
根本原因
このエラーは、ES2015(ES6)で導入された**反復可能プロトコル(Iterable Protocol)**に関連しています。スプレッド構文 [...iterable]
は反復可能オブジェクトを必要としますが、古いJavaScriptバージョン(ES5以前)ではSetオブジェクトが反復可能プロトコルを実装していません。
解決方法
方法1: TypeScript設定の変更(推奨)
最も直接的な解決策は、tsconfig.json
の target
オプションをES2015以上に設定することです:
{
"compilerOptions": {
"target": "es2015",
// または "es6", "es2017", "es2020" など
"lib": [
"dom",
"dom.iterable",
"esnext"
],
// その他の設定...
}
}
TIP
target
を変更した後、downlevelIteration: true
は通常必要ありません。このフラグは、ES5以下をターゲットにしながら、ES2015+の反復機能を使用したい場合のためのものです。
方法2: Array.fromを使用する
target
を変更できない場合、Array.from()
を使用してSetを配列に変換できます:
// スプレッド構文の代わりにArray.fromを使用
exercicesId = Array.from(new Set(exercicesId));
方法3: filterメソッドを使用する
ES5互換の方法で重複を削除する場合は、filter
メソッドを使用します:
exercicesId = exercicesId.filter((value, index, array) =>
array.indexOf(value) === index
);
React/TypeScriptプロジェクトでの注意点
Create React Appなどのテンプレートを使用している場合、デフォルトでES5ターゲットが設定されていることがあります。この場合:
target
をES2015以上に変更するReact.Node
をReact.ReactNode
に変更する必要がある場合がある
// 変更前
function Component(): React.Node {}
// 変更後
function Component(): React.ReactNode {}
推奨設定
最新のブラウザとJavaScript環境を対象とする場合、以下の設定が推奨されます:
{
"compilerOptions": {
"target": "es2020",
"lib": ["dom", "dom.iterable", "esnext"],
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": false,
"forceConsistentCasingInFileNames": true,
"jsx": "react-jsx",
"jsxImportSource": "react"
}
}
WARNING
skipLibCheck: false
に設定すると、サードパーティライブラリの型エラーも検出されますが、ビルド時間が長くなる可能性があります。
まとめ
Set<unknown>
の反復エラーは、TypeScriptのターゲット設定が原因で発生します。最新のJavaScript機能を安全に使用するには、target
をES2015以上に設定することが最も簡単で効果的な解決策です。プロジェクトの制約によってターゲットを変更できない場合は、Array.from()
や filter()
メソッドを使用する代替手段があります。