前提
JavaScript業務利用歴4年ほど
TypeScriptは静的型付け版JSくらいの認識
感想
※引用文は要約したものです
出典:鈴木僚太「プロを目指す人のためのTypeScript入門 安全なコードの書き方から高度な型の使い方まで」, 技術評論社, 2022年
基本的な文法編
型があることにより、適切な関数名とコメントがあればプログラムの解読に関数の中身を読む必要はなくなる
TypeScriptって何がいいの?と聞かれたらまず答えたいメリット
TS導入するべきか悩むときは以下の基準で判断できると良さそう
JSで下記が当然になっているような規模の開発ではTSの恩恵を受けられそう
- 関数を呼び出したい時、全部読んで適切な引数の型、返り値の型を把握
- とりあえず動かす→ランタイムエラー→とりあえず動かす… のループ
enumはJavaScriptにはない独自仕様(=ランタイムに干渉する)のため使用は非推奨
enumの代替策はこちらの記事が参考になりました↓
if(x == null) をしたいときは論理演算子??を使おう
可読性向上系
??自体はJSの機能ですが、2020年に標準仕様として制定されたらしく知りませんでした
こういったJS自体の機能についても紹介されています
オブジェクト編
構造体の最後のプロパティにも , を付けるのがトレンド
こういうことです
const obj = {
foo: 555,
bar: "うひょー", //←これ
};
言語によってはエラーになるため違和感は拭えないですが、行数が変化したときにGitログがシンプルになるなど実利があるとのこと
末尾に,があるのは文章として見ても違和感があるため、プロジェクトで統一したければコーディングルールへの記載やフォーマッターでルール作成は必須かなあと思います
末尾コンマ全部消しておきました!が発生します(経験済)
オブジェクト型のプロパティで再代入しないものにはreadonyを付けよう
type MyObj = {
readonly foo: number;
}
const obj: MyObj = {
foo: 123,
};
obj.foo = 1; //readonlyのため、ここでエラー
プロパティ用のconstですね
逆に言うとオブジェクト自体をconstで宣言していても、プロパティはreadonlyでない場合変更できてしまいます(constで宣言した配列も同様に、要素の再代入ができてしまう)
保守性向上系
関数
アロー関数式をコールバック関数として使おう
type Book = {title: string; author: string };
const books: Book[] = [
{ title: "TypeScript入門", author: "正男"},
{ title: "TypeScript上級", author: "浩二"}
];
たとえば、上記のような本の配列から各要素の題名だけを抽出したい、などの処理はよくあると思います
for-of文で実装すると以下のようになります
const titles: string[] = []; //結果格納用の配列を宣言
//各要素を取り出して結果格納用配列に入れる
for(const b of books){
titles.push(b.title);
}
console.log(titles);
//> ["TypeScript入門", "TypeScript上級"]
コールバック関数とアロー関数式だとこうなります
//各要素を取り出して結果格納用配列に入れる
const titles = books.map((b: Book): string => b.title);
console.log(titles);
//> ["TypeScript入門", "TypeScript上級"]
※アロー関数式(ここでは同時にコールバック関数)は以下の部分
(b: Book): string => b.title
Book型の引数を受け取り、そのtitleプロパティをString型で返却する処理ですね
コールバック関数を受け取っているのは配列booksのmap関数になります
for-ofとコールバック関数の使い分けとしては以下になるかなと思います
- for-ofでは配列の各要素を取り出して複雑な処理をしたい場合に適切
- コールバック関数のほうは「配列の各要素に対して何かしらの処理を実行後、新しい配列を作る」ということが明瞭に伝わるため、単純処理をしている場合に適切
例のようなパターンであれば、副作用がないことが簡単に伝わるためコールバック関数を用いることが適切か
返り値の型は明記したほうがエラー分析時などに便利
変数の型もそうですが構文エラーになるわけではないので省略しがち
ただ、エディタの補助機能やAIアシスタントなどはあくまでもプログラムにミスがないことを前提に役立つものなので二重チェックの意味でも型は記述したいですね
クラス
override修飾子とnoImplicitOverrideコンパイラオプションを使おう
オーバーライドしたつもりがタイプミスで新規関数を作成していた…みたいなパターンがあるかと思います
このパターンは、
- 関数名タイピング時にエディタの補完が入らない
- 継承したメソッドが呼び出せてしまう
- そもそも継承しているメソッドのため処理が類似しており、結果が想定と異なることに気づきにくい
こういった性質のため発生しやすい上に原因究明まで時間がかかったりします
保守性に大きく貢献する機能であり、Javaでも@Overrideなどが古くからありますね
一方TSでは2021年に実装されたようです
クラスってあんまり使われてないのでしょうか…
→次回、著者の方のリポジトリを覗いてみた で検証予定
まとめ
本書ではさらに、高度な型/TypeScriptのモジュールシステム/非同期処理など
使いこなせると便利な機能について紹介されています(感想が書けるほど理解が深まっていないため引用は省略します)
理由付きで「使わないほうが良い機能」や「使いすぎに注意な機能」について説明があるためバッドプラクティスの勉強にもなります
TSの勉強で読み始めたつもりでしたが、JSの機能や型のメリットを最大限活かす方法などについて体系的にまとめられていました
「とりあえず動く」コードは書けるけど、「保守性の高い」コードを書いていきたいという方に入門として適した書籍でした
早速実践して行きたいと思います
次回予定→著者の方のリポジトリを覗いてみた