anyとunknownの違い
any, unknown型はどのような値も代入できます。
tsconstany1 : any = null;constany2 : any =undefined ;constany3 : any = true;constany4 : any = 0.8;constany5 : any = "Comment allez-vous";constany6 : any = {x : 0,y : 1,name : "origin",};constunknown1 : unknown = null;constunknown2 : unknown =undefined ;constunknown3 : unknown = true;constunknown4 : unknown = 0.8;constunknown5 : unknown = "Comment allez-vous";constunknown6 : unknown = {x : 0,y : 1,name : "origin",};
tsconstany1 : any = null;constany2 : any =undefined ;constany3 : any = true;constany4 : any = 0.8;constany5 : any = "Comment allez-vous";constany6 : any = {x : 0,y : 1,name : "origin",};constunknown1 : unknown = null;constunknown2 : unknown =undefined ;constunknown3 : unknown = true;constunknown4 : unknown = 0.8;constunknown5 : unknown = "Comment allez-vous";constunknown6 : unknown = {x : 0,y : 1,name : "origin",};
ちなみに逆の概念としてどの値も代入できないneverという型もありますが、今回は説明を省きます。
any型に代入したオブジェクトのプロパティ、メソッドは使用することができます。
tsconsole .log (any4 .toFixed ());console .log (any5 .length );console .log (any6 .name );
tsconsole .log (any4 .toFixed ());console .log (any5 .length );console .log (any6 .name );
一方、unknown型に代入したオブジェクトのプロパティ、メソッドは使用することができません。使用できないどころか、実行することができません。
ts'unknown4' is of type 'unknown'.18046'unknown4' is of type 'unknown'.console .log (. unknown4 toFixed ());'unknown5' is of type 'unknown'.18046'unknown5' is of type 'unknown'.console .log (. unknown5 length );'unknown6' is of type 'unknown'.18046'unknown6' is of type 'unknown'.console .log (. unknown6 name );
ts'unknown4' is of type 'unknown'.18046'unknown4' is of type 'unknown'.console .log (. unknown4 toFixed ());'unknown5' is of type 'unknown'.18046'unknown5' is of type 'unknown'.console .log (. unknown5 length );'unknown6' is of type 'unknown'.18046'unknown6' is of type 'unknown'.console .log (. unknown6 name );
これだけ見るとunknown型よりもany型の方が優れていると思われるかもしれませんがそうではありません。any型は言い換えればTypeScriptが型のチェックを放棄した型であり、そのためなんでもできます。any型を使うということはTypeScriptでせっかく得た型という利点を手放しているのと同じです。
これでは存在しているエラーはコンパイル時には気が付けず、ソフトウェアをリリースしたあと実際のユーザーが使ったときに実行時エラーとなります。それが不具合報告や、クレームとなり、被害が拡大していきます。
any型に関しては、次のような無茶なコードもTypeScriptは一切関与せず、実行してみてプログラムが実行時エラーになる、初めてこのプログラムが不完全であることがわかります。
tsconsole .log (any6 .x .y .z );
tsconsole .log (any6 .x .y .z );
unknown型は一貫してTypeScriptがプロパティ、メソッドへのアクセスを行わせません。そのため実行することができず、意図しないランタイム時のエラーを防止します。
ts'unknown6' is of type 'unknown'.18046'unknown6' is of type 'unknown'.console .log (. unknown6 x .y .z );
ts'unknown6' is of type 'unknown'.18046'unknown6' is of type 'unknown'.console .log (. unknown6 x .y .z );
TypeScriptのプロジェクトを作る時に必要なtsconfig.jsonにはこのany型の使用を防ぐためのオプションとしてnoImplicitAnyがあります。既存のJavaScriptのプロジェクトをTypeScriptに置き換えていくのではなく、スクラッチの状態からTypeScriptで作るのであればこの設定を入れるとよいでしょう。