Skip to content

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.jsontarget オプションをES2015以上に設定することです:

json
{
  "compilerOptions": {
    "target": "es2015",
    // または "es6", "es2017", "es2020" など
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    // その他の設定...
  }
}

TIP

target を変更した後、downlevelIteration: true は通常必要ありません。このフラグは、ES5以下をターゲットにしながら、ES2015+の反復機能を使用したい場合のためのものです。

方法2: Array.fromを使用する

target を変更できない場合、Array.from() を使用してSetを配列に変換できます:

typescript
// スプレッド構文の代わりにArray.fromを使用
exercicesId = Array.from(new Set(exercicesId));

方法3: filterメソッドを使用する

ES5互換の方法で重複を削除する場合は、filter メソッドを使用します:

typescript
exercicesId = exercicesId.filter((value, index, array) => 
  array.indexOf(value) === index
);

React/TypeScriptプロジェクトでの注意点

Create React Appなどのテンプレートを使用している場合、デフォルトでES5ターゲットが設定されていることがあります。この場合:

  1. target をES2015以上に変更する
  2. React.NodeReact.ReactNode に変更する必要がある場合がある
typescript
// 変更前
function Component(): React.Node {}

// 変更後
function Component(): React.ReactNode {}

推奨設定

最新のブラウザとJavaScript環境を対象とする場合、以下の設定が推奨されます:

json
{
  "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() メソッドを使用する代替手段があります。