TypeScriptエラー「Unsafe assignment of an error typed value」の解決策
問題の説明
TypeScriptコードでオブジェクトのプロパティに動的にアクセスする際、以下のESLintエラーが発生します:
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
型と推論された値を指しています。
エラーの根本原因
型推論の限界:
- 初期化
{ 0.1: 'bar' }
だけでは、TypeScriptはmap
を{ 0.1: string }
型と推論 - 未定義のプロパティへのアクセスは
any
型とみなされる
- 初期化
動的アクセスの危険性:
tsmap[x] // xはランダムな数値 → 存在しないキーの可能性
- コンパイラは
map[x]
の型をany
と判断(既定の動作) any
をstring型変数に代入すると型安全性が崩れる
- コンパイラは
ESLintルールの動作:
@typescript-eslint/no-unsafe-assignment
ルールはany
型の代入を検知し警告します
解決方法3選
方法1: 明示的な型宣言(推奨)
map
の型をRecord<number, string>
で明示します:
const map: Record<number, string> = {
0.1: 'bar',
};
const x = Math.random();
const s: string = map[x]; // エラー解消
これで未定義キーもstring | undefined
と推論され、any
が排除されます。
方法2: 型アサーションの使用
一時的な対処法として型アサーションを追加:
const s: string = map[x] as string; // 明示的にstringを主張
WARNING
この方法はランタイムエラーを防げないため、限定的な使用に留めましょう。
方法3: インデックスシグネチャの定義
オブジェクト型に直接インデックスシグネチャを記述:
const map: {
[key: number]: string;
} = { 0.1: 'bar' };
補足アドバイス
ESLintサーバーの再起動: 型定義を修正してもエラーが消えない場合、VSCodeでESLintサーバーを再起動:
bashCmd/Shift+P → "ESLint: Restart ESLint Server"
型定義の依存関係チェック: 外部モジュールの型定義に問題があると同様のエラーが発生:
ts// 例: 相対パスが不正な型定義ファイル import { ProblematicType } from './myTypes/myTypes/';
strictモードの活用:
tsconfig.json
でstrict: true
を設定すると、初期段階でany
推論を防止できます:json{ "compilerOptions": { "strict": true } }
予防的ベストプラクティス
手法 | 効果 | 推奨度 |
---|---|---|
Record 型の使用 | 動的キーの型安全性を確保 | ★★★ |
オプショナルチェーン(?. ) | undefined アクセスを防止 | ★★☆ |
値存在チェック | 実行時エラーを回避 | ★★☆ |
// 安全なアクセス例
const s = map[x] !== undefined ? map[x] : 'default';
このエラーは型システムの意図しないany
漏出を警告しています。オブジェクトのキーが動的になる場合は、事前に型を明示することでほとんどの問題を予防可能です。