TypeScriptにおいて、どんな値でも代入できる「なんでも入る型」として any 型がありますが、型チェックを放棄してしまうため安全ではありません。代わりに、どんな値でも代入できるが、実際に使用する前に「型チェック(型ガードなど)」を強制する、より安全な推奨される型はどれですか?
解説
正解と要点正解は unknown です。any と同様にどんな値でも入れられますが、プロパティへのアクセスやメソッド呼び出しの前に、必ず型の特定(型ガード)を強制するため、安全性が保たれる型です。なぜその答えなのか検索エンジンでよく調べられる「TypeScript unknown any 違い」の答えがまさにこれです。any はコンパイラによる型チェックを完全に無効化してしまうため、存在しないメソッドを呼んでもエラーにならず、実行時にアプリがクラッシュする危険があります。一方、unknown は「今は型が分からないから、実際に使う前にチェックしてね」とコンパイラが教えてくれます。つまり、any は型システムの放棄、unknown は型システムの維持という明確な違いがあります。 他の選択肢について、object はプリミティブ値(文字列や数値など)を代入できません。never は「絶対に値を持たない」ことを示す型であり何も代入できず、void は主に関数の戻り値がないことを示す型であるため不正解です。背景・仕組みTypeScriptは静的型付け(コードを実行する前に型を決めて安全性を担保する仕組み)の言語です。しかし、外部APIからのレスポンスやユーザーの入力など、実行するまで中身の型が本当に分からないケースがどうしても存在します。このような場面で、とりあえずデータを受け入れつつも、後の処理で安全性を強制する「安全なany」として、TypeScript 3.0から unknown 型が導入されました。よくあるミスとエラーunknown 型の変数に対して、型ガード(型の特定)をせずにそのままプロパティにアクセスしたりメソッドを呼び出そうとすると、コンパイラがエラーを出します。初学者はここで 「Object is of type unknown.」 というエラーによく遭遇します。/* エラーになるアンチパターン / let data: unknown = 'hello'; / 型が不明なまま length プロパティにアクセスしようとしてエラーになる / console.log(data.length);実務での活用例現場のプロジェクトでは、APIレスポンスの受け皿や、try...catch 構文で捕捉した error オブジェクトの型として非常によく活用されます(最近のTypeScriptではcatchしたerrorはデフォルトでunknownになります)。具体的には、以下のように typeof などの Type Guard(型ガード) を使って、安全に処理を行うのがベストプラクティスです。/ 実務で推奨される安全な処理(型ガード) / function processData(data: unknown) { if (typeof data === 'string') { / このifブロックの中では、data は確実に string 型として扱われる */ console.log(data.toUpperCase()); } else { console.log('データは文字列ではありません'); } }