白猫のメモ帳

C#とかJavaとかJavaScriptとかHTMLとか機械学習とか。

TSKaigi2024レポ

こんばんは。

TSKaigi2024にオンライン参加したのでちょっとだけ感想を。
カンファレンス的なものの参加ってめちゃくちゃ久しぶりなのですが、イベント参加したら何か書けと偉い人も言ってる気がするので簡単な感想と聞きながら書いてたメモで。
変に矢印とか入れちゃったんで箇条書きになってないとか、話の内容と個人の感想が混じってたりするんですがそのあたりは許してくださいということで。(だから最初からmarkdown的なもので書けと…)
LTもいくつか聞いたんですが、そこは省略で。

Keynote: What's New in TypeScript

MicrosoftのTypeScript Principal Product Managerの方のセッション。
オンラインの配信トラブルで15分ほど遅れで開始。

同時翻訳があるのはうれしいんですが、字幕とスライドのどっちを見たらいいんだ状態にはちょっとなりがち。
そもそもTSにまだそんなに詳しくないので、全体的に「へー」と思いつつもあんまり苦労した思い出がないので、やっぱり普段使う言語で便利機能が追加されるときほどの感動がないのはちょっと寂しいですね。

・TSのニーズ高いな(Rust強いな)
・Inferの型絞り込み便利そう
・filterのラムダがtype guard的に動くのか(というかもともとそうじゃないのか…)
コンパイル速度とかは業務でちゃんとしたでかいサイズ扱わないと目が向かないところだなー
・型を型だけでコンパイルするって面白い
・書いてる側としては戻り値も型推論されちゃうから省略しがちだけど、使う側としては確かに書いておいてほしいかも

フロントエンドもバックエンドもインフラも… 全てをTypeScriptで統一したらこうなった!

JSは動かしてみないとわからない綱渡りっていうのは確かにそうだなと。
インフラも込みでTS率95%超えとかできるんですね…。

・レイヤー参考になるー!(TS関係ない)
GitHub Codespacesで環境構築いいな
・型はzodでスキーマ定義→inferで型に変換(スキーマと型ってごっちゃにしがちかもしれない)
・ZodiosはコードがAPI定義書っぽくていいな
・統一すると全員フルスタックエンジニアになって、分業によるタスクの偏りは減る
・知識の共有が開発言語の違いによって阻害されない

TypeScript 関数型バックエンド開発のリアル

伊藤さんのTSで関数型DDDの話は「Domain Modeling Made Functional」を読んでいい感じに取り入れられないかと思っていた時にいろいろ参考にさせてもらっていました。
やっぱり型をちゃんとするとコンパイル時点でおかしいことに気付けるし、ユニットテストの分量も減らせるのがいい。

ドメインレイヤー以外はオブジェクト指向とあんまり変わらない
・Union型を使ってとにかく型をよく使う(オブジェクトだけじゃなくて関数も)
・オブジェクトの変更は関数適用による状態遷移でイミュータブル
→やりたいんだけどC#だとUnion型、分割代入、スプレット構文とかがなくてTSがうらやましく感じる
・命令的よりも関数的な方が明示的に変化が現れる
→型を厳密に書けば書くほどコンパイラがちゃんとチェックしてくれるのはいいよね
・データ取得とかデータ保存とかは普通に書いていい(あくまでドメイン層だけ)
→IOでサンドイッチ(=オニオンアーキテクチャ
ドメインレイヤーをIOと分離することで、ドメインレイヤーを関数型スタイルにする余地が生まれる
ユニットテストでモック差し込むときとかもなるべく薄くはぎ取って差し込みたいよね
・Resultパズルがつらい
→Result.combineでmapする、fromThrowable/fromPromiseとか使う
→一直線のWFならいいんだけど、この辺り単純なRailwayの考え方だけだと足りないんだよなと最近悩んでいるところ

複雑なビジネスルールに挑む:正確性と効率性を両立するfp-tsのチーム活用術

エラーをいっぺんに出してっていう話は確かによくあるなと。
Visitorパターンとか使って貯めこんでもいいけど、合成できちゃうならResultでつなげていくのは確かに楽でいいですよね。

・セルの検証→行の検証→表の検証ってステップが複数ある
・関数型でエラーの合成してEiher型(Result型)で返す
・例外だと複数のエラーを同時に伝搬しづらい
→これってRailwayのエラー側に流すのと共存できるのかしら
・エラーの合成自分ではやりたくない
→fp-tsを使うとエラーの合成がしやすい(pipeとかmapとか使って合成できる)
・公称型を利用して検査の関門を一つに絞る
・やっぱ関数型の学習コストは結構高い
→スコープを絞るとかペアプロ・モブプロするとか
・パフォーマンス的にいいんだっけは要検証

Step by Stepで学ぶ、ADT(代数的データ型)、モナドからEffect-TSまで

型定義を見ると挙動がわかるから宣言的って話はそうだよなーと思いつつ、型パズルをするのをわかりやすいとみなせるかは慣れにもよりそうだなと。
非同期周りはどうしても複雑になりがちなので、Effectで吸収してくれるのはありがたい。

・validateってtrue/falseのどちらが成功か人によって違う
・どんなエラーが投げられるかわからないし読みづらい
・union型でどんなエラーが返ってくるか型で分かる
・Rightはvoidでもいいよ(Rightって正しいだからエラーはLeftへ)
・TSの言語仕様としてpipeはいるかも?
→知らなかったので調べよう
・if文がなくなってデータフローとして表現できるけど型パズルにはなる
・非同期のためのTaskとTaskEither
→実態は()=>Promise
→実行されるとTaskEitherからPromiseEitherになる
・Effect
→PromiseとTask区別せずに全部Effectで揃うので楽
・処理が小さくなるのでメンテナンス性が上がるし、ユニットテストが書きやすい
→うんうん

サービス開発におけるVue3とTypeScriptの親和性について

Reactは多少触ったことがあるんですが、VueはノータッチだったのでこれがVueならではの話なのかの判断が難しかったですね。
TSで型ついてうれしーとか雑に思ってるけど、やっぱりそこに至るまでにはいろいろな苦労があるんだなと。

・親和性=型付け×論理構成
・Props Drilling/Event Emitting
・Vue2は型の恩恵がいまいちだった
→結構対応が大変だった
コンポーネント自体は対応できてもVSCodeとかのツールへの対応が大変だった(vuejs/lauguage-tools)
・フロントエンドってコンポーネントに分けるところまではできても、コンポーネントの中散らかしがちだよなぁ…
・PiniaをつかってProvide/Injectを使うとスコープを制限できる
→なんでもグローバル…うっ頭が…

TypeScriptとGraphQLで実現する型安全なAPI実装

APIからの型付けは祈りでしかない。確かに。
GraphQL自体をつかっていないので、なるほどこうやって作っていくんだなという感じで面白かったです。

・型をつけるとは
APIの仕様をスキーマで定義、スキーマから型を生成(自動で)、生成された型で実装
APIに型をつける技術としてはOepnAPI、gRPC、GraphQLあたり
・GraphQL Codegen

クライアント側

スキーマから生成した型ではなくてクエリから生成した型を使う
スキーマから生成すると参照側で省略した値が消えてエラーになっちゃう
・すべての子が必要とするデータを知ってる必要がある
→フラグメントコロケーション
→クエリで指定するフィールドをフラグメントとして親に渡してマージする(コンポーネントごとに定義)
・定義してないところでも使えちゃうやんけ(ダックタイピング的な話ね)
→フラグメントマスキングでエラーにしてくれるけど、型が複雑になるデメリットはある

サーバ側

・サーバ側はクエリじゃなくてスキーマ側からつくるでいい
・いらないもの取るってどうするの?
→Field Resolver(必要なものが入ってるときだけ遅延実行される)
→これ割と前から疑問だったのでなるほどなと思うなどする
・mappersでresolverが使う型を指定できる

Prettierの未来を考える

Prettier使っていますが、作る人としてはこんなこと考えてるんだなーと。
個人的にはnode.jsって結構いろんなもの組み合わせる必要があって難しいなと思ってたんですが、詳しい人も難しいならそりゃ難しいわと思いました。

・コーディングスタイルって個人の価値観によっていろいろある
→争いをなくす
・最近の言語だと言語側がこういうの提供されてたり(GoとかRust)
・単品で使うと便利なんだけど、ESLintとかと一緒に使うと…
→コードフォーマッターであってリンターじゃない
・しかもTSだともっといっぱい入れないといけない
・DenoってTS直で使える(node.jsじゃないよ)
・node.jsつかうならBiomeがアツイ
→DenoもBiomeも使ったことないので試してみたい
・パーサーを自分で持ってないのは強いなー

というわけで

イベントスタッフのみなさま、発表者のみなさま、スポンサーのみなさま、参加者のみなさま。
おつかれさまでした。