できない.dev

TypeScript で catch の「Object is of type 'unknown'」が解決できない

TypeScript 4.4 以降は useUnknownInCatchVariables(strict で既定有効)により catch の変数が unknown 型になる。
現行版は TS18046「'e' is of type 'unknown'」、旧版は TS2571「Object is of type 'unknown'」として出る。
instanceof や型ガードで絞ってからアクセスする。

公開: 更新:

要約

Object is of type 'unknown'.catch ブロックで出るのは、TypeScript 4.4 以降の useUnknownInCatchVariablesstrict: true で既定有効)により、catch (e)eany ではなく unknown 型になったため。unknown はそのままでは何もできないので、型を絞ってから 使う。
これは安全側に倒した正しい挙動で、握り潰さず対処する。

エラー文言はバージョンで変わる: 同じ原因でも、現行の TypeScript(5.x 系など)で catch 変数を絞らずに使うと error TS18046: 'e' is of type 'unknown'.e は変数名)が出る。
それ以前のバージョンや「unknown 値へのプロパティアクセス全般」では error TS2571: Object is of type 'unknown'. と表示される。どちらも unknown を絞っていないことが原因で、対処は同じ
この記事下部の「## 実行例」は TypeScript 5.9 での実測のため TS18046 を記録している。

よくある原因

  1. strict 既定: strict: true に連動して useUnknownInCatchVariables が有効になっている
  2. 未ナローイングのアクセス: catch (e) { console.log(e.message) } と直接プロパティを読んでいる
  3. reject 値の前提: Promise の reject や throw される値を any 前提のコードで扱っている
  4. 旧コードの移行: 4.4 より前に書かれた古い例外処理コードをそのまま移している

解決策

1. instanceof で絞る

try {
  doWork();
} catch (e) {
  if (e instanceof Error) {
    console.error(e.message);
  } else {
    console.error(String(e));
  }
}

Error 以外が throw される可能性も String(e) で受ければ漏れない。

2. 型ガード関数で検証する

function hasMessage(e: unknown): e is { message: string } {
  return typeof e === "object" && e !== null && "message" in e;
}
 
try {
  doWork();
} catch (e) {
  if (hasMessage(e)) console.error(e.message);
}

e is { message: string } の述語型で、必要な形だけを安全に取り出す。

3. any の多用を避ける

個別に catch (e: any) と書くこともできるが、型安全をその場で捨てることになる。
例外処理こそ未知の値が来る場所なので、unknown を絞る方針を基本にする。
詳しい背景は TypeScript 4.4 リリースノート(新しいタブで開く) を参照。

4. 移行期だけ設定で戻す

{
  "compilerOptions": {
    "useUnknownInCatchVariables": false
  }
}

大量の旧 catch を一度に直せないときの一時退避。
各オプションの意味は tsconfig の useUnknownInCatchVariables(新しいタブで開く) にある。
最終的には unknown を絞る形へ寄せる。

実行例

実際に上記の手順を node:20 環境で動かすと、useUnknownInCatchVariables が有効な状態の src/bad.tsTS18046: 'e' is of type 'unknown'. が発生し(終了コード 2)、instanceof Error による絞り込みおよび型ガード関数による絞り込みのいずれもコンパイルエラーなし(終了コード 0)で通過することが確認できる。

Version 5.9.3
$ npx tsc
src/bad.ts(8,17): error TS18046: 'e' is of type 'unknown'.
tsc 終了コード: 2
$ npx tsc
tsc 終了コード: 0
$ npx tsc
tsc 終了コード: 0

— 2026-08-02 時点の出力

この記事は役立ちましたか?