「any型はダメ!」TypeScriptを学ぶ時に一番はじめに学びます。
結局どうすればいいのか?知識が曖昧だったので調べ直してみることにしました!
【本記事の結論】
any型を使うことは、プロダクトに対して地雷を設置していくような行為。
利用時にはチームで話し合った上で利用の是非について決定しないといけないもので気軽に使えるものではない。
TypeScriptのany型の問題点とは?
実行エラーが発生するようなコードでコンパイル時にエラーを発生させないことだと言えます。
TypeScriptは、変数や関数に静的な型付けをすることでコードのバグを発見できることにあると思います。
any型を利用することはコンパイラーが型のチェックを行わない、TypeScriptの利点を自ら放棄してしまっているような状態になってしまいます…。
TypeScriptはコンテキストから型を推論できない時は、型をany型として扱います。
tsconfig.jsonにnoImplicitAny: true
を設定することで暗黙のanyを禁止できます!
any型を利用したいと考えたときにプログラムの設計を変更してロジックをシンプルにすることを検討しany型が本当に適切か?をよく検討してください。
any型の定義を定義してしまうことはプロダクトにとって重大な罪であると認識することが重要だと感じました。
any型の利用について
any型は技術負債になるため原則は使わないとされつつ、やむを得ずany型を使用する場合が存在しているからです。
下記の記事で詳しくかつ、わかりやすく解説されているのでこの記事では長く記載しません。
自身のメモとしてany型をしたいと思ったときに使いたい記述例を残しておきます。
オブジェクトにanyを使いたくなったとき
- function(obj: any): number {
+ function(obj: {num?: number }): number {
// 処理省略
}
オブジェクトで、num
プロパティを持ってなくてもいいけど、持っている場合はプロパティnum
はnumber型とする。
の意味になるらしい。
型アサーションas
を利用する
型を強制的に修正する他mの構文なのでこちらもany型と同様にできるだけ使わない方が良いとされています。
ただ、as
を利用せざるを得ないパターンもあるらしく、それをメモとして残します。
function hode<T extends object>(obj: T): T {
- const hogehoge = {};
+ const hogehoge = {} as T;
for (const key in obj) {
hogehoge[key] = obj[key];
}
return hogehoge;
}
const hogehoge = {}
の部分の型が{}
として推論されます。
関数はT型を返そうとしているためエラーになります。
そこでas
を使ってT型であるとすることでエラーを解消できます。
as
は強制的に型を変えるので、TypeScriptの型システムに抗う行為になるため危険な拡張だと言えます。
ただ、今回のパターンだと関数の中に危険性が閉じ込められている。
スコープが切られているという点でas
の利用を許容するという判断ができます。
がんばらないTypeScriptというアプローチもある
運用歴の長いサイトではいきなり全てをTypeScriptに置き換えていくのは困難だと思います。
教育や運用などいろんなコストが必要になります。
技術的負債も多い場合はさらにリソースの確保が難しくなると言えます。
ではやめるか?となるのではなくて、少しずつ取り入れていくアプローチとして「がんばらないTypeScript」というのが提唱されています。
少しでもTypeScriptを利用して安全な状態にしておく方がいいよね…の精神に則ってできる一部だけ進めるというアプローチです。
【まとめ】TypeScriptのany型について
本記事ではany型について書きました。
any型について考え方を改めることができました。
どこかでany型を定義するのは仕方ないと考えてしまっていました。
とにかくany型は使わない
TypeScriptの熟練度はまだまだですが、any型の利用だけは厳格に守っていきたいと改めて思いました。
参考記事