天の月

ソフトウェア開発をしていく上での悩み, 考えたこと, 学びを書いてきます(たまに関係ない雑記も)

Effective TypeScript - Forkwell Library #89に参加してきた

https://forkwell.connpass.com/event/350245/

こちらのイベントに参加してきたので、会の様子と感想を書いていこうと思います。

会の概要

以下、イベントページから引用です。

第89回目では『Effective TypeScript 第2版 ―型システムの力を最大限に引き出す83項目』を取り上げます。 本書では、TypeScriptを最大限に活用するための83項目のアドバイスを、実践的なコードとともに提供しています。

多くの高度な機能を持つTypeScriptを使いこなし、より効果的なTypeScriptコードを書けるようになるためのTipsが詰め込まれています。 そんな本書のポイントを訳者である 今村 謙士 氏に講演をしていただきます。

TypeScriptをマスターしたい人、現状使っているがよりスキルアップしたい人におすすめです!

会の様子

今村さんの講演

書籍概要

最初に書籍のざっくり紹介として、初心者向けではないものの難解ではないので初心者が読めない本ではなく、どんなことを意識するといいのかがわかる書籍だという話がありました。

推し1 : 項目9(型アノテーションを型アサーションより優先的に使用する)

型エラーを簡単に消せる型アサーションに頼りすぎる危険性や型アサーションが有効な状況を記載している点が、今村さんの実践経験からして共感できるポイントが多くおすすめだということでした。

推し2 : 項目25(進化する型を理解する)

なるべく型アノテーションを減らすことができるパターンが推奨されているものの、初めてのTypeScriptでは非推奨とされているということで、意見が世の中で分かれている点が面白いということでした。

推し3 : 項目29(有効な状態のみ表現する型を作る)

不正な状態をハンドリングするコードが不要になるため実装がシンプルであり、バグの防止もできる非常に有効なテクニックとして共感が強いということでした。

推し4 : 項目48(健全性の罠を回避する)

静的型が実行時の値と互換性があることを保証できる型システムは健全であるとされていますが、TypeScriptは不健全性をある程度許容しているという話が面白いということでした。

特に、不健全性の例で挙げられていたクラス階層における双変性が面白いということです。

推し5 : 項目53(条件型のユニオンでの分配を制御する)

上級者が読んでも読み応えがある項目として推しに挙げたということです。

条件型の挙動を知っていればTypeScriptの上級者と言えるだろうということで、分配がどのような状況で起きるかのルールを利用して型の書き方を工夫して分配の無効/有効を切り替えするテクニックが素晴らしいという話でした。

推し6 : 項目62(レストパラメータとタプル型を使って、可変長引数の関数をモデリングする)

特定文字列と特定の型がリンクするJSの頻出パターンですが、文字列と型の関係をinterfaceで定義する方法が直感的でわかりやすいので身につけておくとすごく役に立つそうです。

推し7 : 項目84(コンパイラーオプションやリンターを使ってコードに規約を適用する)

ここは日本語オリジナルの項目だということで、コンパイラーオプションを使うことでルールが強制されるのがすごくよいという話がありました。

なお、本書は一般的な推奨設定ではカバーできない項目も多いのでややメンテナンスコストが高くなるのは注意だということです。

Q&A

講演の後はQ&Aがありました。以下、質問と回答を一問一答形式かつ常体で記載していきます。

アサーションを使わないでエラーを解消する典型的な方法を知りたい

一番良く見るのは、as constをつけて直すやつ。あとは地道に解決していく系もよくある。

関数型ドメインモデリングをTypeScriptで実践すれば複雑な業務知識をすっきりとコードに落とし込めるか?

あんまり関数型ドメインモデリングに詳しくないのだが可能性はあると思う。

健全性の罠の例はリスコフ違反ではないかと思った

クラスの中に関数をプロパティとしてもたせると今回の例みたいなのはなくなる。

バックエンドのGolangの型をフロントのTypeScriptで自前で型を付けるのは面倒だが、自動でやる方法はないのか?

一般的には標準的なスキーマで型定義しているはずなので、そこから自動生成するのがいいのかなと思う。

関数に対して型アノテーションを使うことは一般的だと思うが、変数に対して型アノテーションを指定して値を受けるシチュエーションはあるのか?

そんなにないシチュエーションかなとは思う。

type aliasとinterfaceの使い分けはどう考えられているのか?

一般的にはinterfaceを使うのがコンパイラーパフォーマンスの観点で一般的には推奨されている。ただ、既存コードがあるならそっちに習う。

interfaceかtypeか、Enumかunionか、悩ましいときがある

unionのほうがいいというのが多数派の意見。Enumは本来のコンセプトを逸脱しているので基本的にはunionを使う。

TypeScriptとJSはなぜあまりClassを使わないのか?

クラスは状態を持つので、関数型とは相容れないというのがある。

書籍翻訳にあたって気を配った部分は?

適当な日本語訳がない技術用語がないものの訳には困った。

TypeScriptの場合例外ではなくエラーを型で定義する仕組みを利用するのが良いのか?

エラーを投げる代わりにリターンするみたいなライブラリを使うのが現実的にはいいのかと思う。

TypeScriptの仕様理解を深めるためにリリースノートを読む以外でやっていることはあるか?

普段コードを書く中で新しい問題にぶちあたったときにその場だけの理解にとめず深掘りするのはやっている。

branded typesを作りたくなったときの手法は本書にあるのか?

ある。

TypeScript以外に好きな言語はあるか?

Scalaとか。

TypeScriptにこれだけ深く関わってきたきっかけは?

早い段階から触っていたから。

バックエンドでTypeScriptを使う場合おすすめのフレームワークは?

逆に知りたいくらい。

進化するanyがnolmplicitAnyで問題にならないのはTypeScriptの処理系仕様のバグみたいなものだと思われるか?妥当なデザインだと思うか?

バグだとは思っていない。好みではない。

Honoはいかがか?

詳しくはないのであまり言えないが良さそう。

複雑な型の分配が多発すると型推論が遅くなると思うがプロファイリングをする方法はなにかあるか?

条件型を作るときに、末尾再帰の最適化が行われるのでそういうのを使ってみる。

Node.jsでTypeScriptのサポートがされるようになってゼロベースで導入するならDenoと比べて処理系のどちらがおすすめか?

Denoはあんまり使っていないので比較が難しい。そんなに両者の評価は変わらないと思う。

symbolをこれまで使ってこなかったのだがどのような活用方法があるか?

JSの予約されたsymbolがあってそれを使うのがまずある。あとは名目的型づけをやるときとか。

会全体を通した感想

色々なTipsがあるんだなあというのはすごい面白くて、特にユニオンでの分配制御の話は面白かったです。

会の本質ではないのですが笑、Q&Aの裁きがすごくて驚きました。