TypeScriptのanyとunknownの違い|どっちも避けるべき?初心者向け整理

TypeScriptのanyとunknownの違い|どっちも避けるべき?初心者向け整理

 

少年A
「anyは使うな」って言われたから、じゃあ型がわからない時どうすんの?
キノ
それ、まさに自分がハマった疑問。答えは「unknown」って型だったんだ

「anyは使うな」で終わっていた理解

前々回、TypeScriptでanyを使うと型チェックが効かなくなる、という話をしました。ただ、そのときの自分は「anyを使わなければとりあえず安全」くらいの理解で止まっていました。

実際にコードを書き進めていくと、「型が何になるか分からないけど、anyは使いたくない」という場面に何度も遭遇しました。そこで出てくるのがunknownという型です。

スポンサーリンク

anyとunknownは何が違うのか

見た目上は、どちらも「どんな値でも入れられる型」という点は同じです。

let a: any = "kino";
let b: unknown = "kino";

a = 123; // OK
b = 123; // OK(代入はどちらもできる)

違いが出るのは、その値を「使おうとしたとき」です。

let a: any = "kino";
console.log(a.toUpperCase()); // 通ってしまう(typoしても気づけない)

let b: unknown = "kino";
console.log(b.toUpperCase());
// Error: 'b' is of type 'unknown'.

anyはその後もずっとノーチェックのままですが、unknownは「型が確定するまで、何もさせてもらえない」という制約が付きます。これが、unknownの方が安全と言われる理由です。

スポンサーリンク

unknownを使うには「型を絞り込む」作業が必要

unknownのまま使おうとするとエラーになる、というのは最初「じゃあ結局使えないじゃないか」と感じたポイントでした。実際には、使う前に型を確認する処理を書く必要があります。

function printLength(value: unknown) {
  if (typeof value === "string") {
    console.log(value.length); // ここではstring型として扱われる
  }
}

typeof value === "string"のようなチェックを通ったブロックの中でだけ、TypeScriptが「ここはstring型で間違いない」と判断してくれます。この仕組みは「型ガード」や「型の絞り込み」と呼ばれています。

面倒に見えるこの一手間こそが、「実行するまで気づけないバグ」を防ぐための仕組みだと分かってからは、unknownに対する苦手意識がだいぶ減りました。

結局、どう使い分ければいいのか

  • 外部から来る、中身が予測できない値(APIレスポンスやJSON.parseの結果など):unknownを使い、使う前に型を確認する
  • anyは基本的に使わない:どうしても必要な場合も、影響範囲を最小限にする
少年A
面倒くさがらずに型を確認する癖をつけろってことね
キノ
うん。最初は面倒だったけど、慣れると逆にこの確認作業がないと不安になってきた

JavaScriptを書いていたときは、値の中身をあまり気にせずそのまま使ってしまうことも多かったので、「使う前に型を確認する」という発想自体がTypeScriptで初めて身についた感覚があります。


 

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です