IT-Q

function isUser(x: unknown): x is User { return typeof x === "object" } という関数がありました。これで安全ですか。

TypeScript は型述語と関数の中身が合っているかを確かめないので、判定が甘ければ間違った値が通ります。公式も、明示した型述語は as と同じくらいしか安全ではないと書いています。

面接官が見ているのは🔴 明示した型述語は検査されず、as と同じだと分かっているか。

これは「const scores = ids.map((id) => scoreMap.get(id)).filter((s) => !!s) と書いたのに、scores が (number | undefined)[] のままで、合計を出すところでエラーになります。どうしますか。」への追撃質問です。

よくある答えと、面談でどう見られるか

  • 安全ではない。TypeScript は型述語の中身が正しいかを確かめないので、オブジェクトなら何でも User として扱われる。必要なプロパティまで確かめる
    その通りです。公式も、明示した型述語は as と同じくらいしか安全ではない、と書いています。
  • 型述語を付けた関数は、TypeScript が中身まで検査するので安全
    検査しません。true を返せば、TypeScript はその型だと信じます。
  • typeof の結果を見ているので、実行時に確かめていて安全
    確かめてはいますが、オブジェクトかどうかだけです。null も typeof では "object" です。
  • unknown を受けているので安全
    受け口が unknown でも、返す判定が甘ければ、間違った値が User として通ります。

模範解答

安全ではありません。

TypeScript は、明示した型述語(x is User)と関数の中身が合っているかを確かめません。true を返せば、その値は User として扱われます。公式のリリースノートも、明示した型述語は型アサーション(as)と同じくらいしか安全ではない、と書いています。

この関数は、オブジェクトでさえあれば User だと判定します。しかも typeof null は "object" なので、null まで User として通します。

型述語を書くなら、使うプロパティの型まで確かめます。数が多いなら、手で書かずに、スキーマから型と検査を同時に作るライブラリを使う方が確実です。

対象: TypeScript 5.x〜7.0 照合した一次資料: 公式ドキュメント 照合: 2026-10-25 最終更新: 2026-10-25
お使いの版で挙動が違う場合があります。誤りに気づいたらこの解説を報告するから教えてください。