Skip to content

TypeScriptエラー「Unsafe assignment of an error typed value」の解決策

問題の説明

TypeScriptコードでオブジェクトのプロパティに動的にアクセスする際、以下のESLintエラーが発生します:

ts
const map = {
  0.1: 'bar',
};

const x = Math.random();
// エラー発生箇所
const s: string = map[x]; // Unsafe assignment of an error typed value

エラーメッセージ:

Unsafe assignment of an error typed value.(@typescript-eslint/no-unsafe-assignment)

このエラーは変数s(string型)にmap[x]の値を代入しようとする際に発生します。メッセージ中の「error typed value」とは、暗黙的にany型と推論された値を指しています。


エラーの根本原因

  1. 型推論の限界:

    • 初期化{ 0.1: 'bar' }だけでは、TypeScriptはmap{ 0.1: string }型と推論
    • 未定義のプロパティへのアクセスはany型とみなされる
  2. 動的アクセスの危険性:

    ts
    map[x] // xはランダムな数値 → 存在しないキーの可能性
    • コンパイラはmap[x]の型をanyと判断(既定の動作)
    • anyをstring型変数に代入すると型安全性が崩れる
  3. ESLintルールの動作: @typescript-eslint/no-unsafe-assignmentルールはany型の代入を検知し警告します


解決方法3選

方法1: 明示的な型宣言(推奨)

mapの型をRecord<number, string>で明示します:

ts
const map: Record<number, string> = {
  0.1: 'bar',
};

const x = Math.random();
const s: string = map[x]; // エラー解消

これで未定義キーもstring | undefinedと推論され、anyが排除されます。

方法2: 型アサーションの使用

一時的な対処法として型アサーションを追加:

ts
const s: string = map[x] as string; // 明示的にstringを主張

WARNING

この方法はランタイムエラーを防げないため、限定的な使用に留めましょう。

方法3: インデックスシグネチャの定義

オブジェクト型に直接インデックスシグネチャを記述:

ts
const map: { 
  [key: number]: string; 
} = { 0.1: 'bar' };

補足アドバイス

  1. ESLintサーバーの再起動: 型定義を修正してもエラーが消えない場合、VSCodeでESLintサーバーを再起動:

    bash
    Cmd/Shift+P "ESLint: Restart ESLint Server"
  2. 型定義の依存関係チェック: 外部モジュールの型定義に問題があると同様のエラーが発生:

    ts
    // 例: 相対パスが不正な型定義ファイル
    import { ProblematicType } from './myTypes/myTypes/';
  3. strictモードの活用: tsconfig.jsonstrict: trueを設定すると、初期段階でany推論を防止できます:

    json
    {
      "compilerOptions": {
        "strict": true
      }
    }

予防的ベストプラクティス

手法効果推奨度
Record型の使用動的キーの型安全性を確保★★★
オプショナルチェーン(?.)undefinedアクセスを防止★★☆
値存在チェック実行時エラーを回避★★☆
ts
// 安全なアクセス例
const s = map[x] !== undefined ? map[x] : 'default';

このエラーは型システムの意図しないany漏出を警告しています。オブジェクトのキーが動的になる場合は、事前に型を明示することでほとんどの問題を予防可能です。