TSKaigi 2024
https://gyazo.com/bea1aefcd1bb0f104ed632a6220f7f88
https://tskaigi.org/
TypeScript
中野セントラルパーク カンファレンス
Keynote
Daniel Rosenwasser
Microsoft / TypeScript Product Manager
2016年のGitHub Octoverseでは下位だった
2018年には急にベスト10入りした
2020年にはトップ4になった
2023年にはトップ3になった
100%TypeScript化は20.7%
人がTypescriptに費やす時間が増えてきた
npm downloadsは2兆件を超えた
5.4と5.5の機能を紹介
NoInfer
TypeScript 5.5で型述語を推論できて最高。配列のfilterも型安全に
パフォーマンスとスケーリング
DX向上
--isolatedDeclaration
トレードオフがある
TypeScript ASTを利用したコードジェネレーターの実装入門
TSKaigi 2024 TypeScript ASTを利用したコードジェネレーターの実装入門 | ドクセル
Himenon
株式会社ハイヤールー / ソフトウェアエンジニア
https://github.com/Himenon/openapi-typescript-code-generator
https://github.com/Himenon/tskaigi-2024-code-sample
TypeScript AST入門
抽象構文木
利用しているもの
Compiler API
Language Server Protocol
TypeScript AST Viewer
"Hello"は
ExpressionStatement
StringLiteral
になる
ASTでよく使われる用語
root
node
走査(traverse)=各nodeを訪問すること
幅優先探索 / 深さ優先探索
Visitorパターン
工程
1. ソースコードからASTへ変換(Parse)
2. 木の走査をしながらNode変換(Traverse)
3. ASTからソースコードへ変換(Unparse)
コードジェネレーター実装入門
解決してくれる課題と構造
コード生成機は入力された仕様やスキーマに依存する
入力や成果物もその分無数の選択肢が生まれる
ジェネレーターの開発者の母数が少ない
実装方法
Factory Codeを使う
経験則から得られたアンチパターンと対策
不正な入力値もできる限り推論を行ってコード生成していた
利用しないパラメーターも記述する必要があるため、冗長になるためラッパーが欲しくなる
ASTとPlain Textをハイブリットに書きたい
sourceFileのstatementsを抽出する
ts-morphを使用する
テンプレートにASTを使うかStringを使うか
実装量
Template Literalだと最小
独自構文になるかどうか
ASTはルールに従える
原理的に思い出しやすくなる
ランチセッション
TypeScript化の旅: Helpfeelが辿った試行錯誤と成功の道のり
寺本大輝
株式会社Helpfeel / プロダクトエンジニア
新サービス Progate Path の演習で TypeScript を採用して見えた教材観点からの利点と課題
島津 真人
株式会社Progate / CTO
PMF達成の立役者!Full TypeScript Architecture の選定背景と構成(10分)
丹羽 健
アセンド株式会社 / 取締役CTO
TypeScript 関数型バックエンド開発のリアル
TypeScript 関数型スタイルでバックエンド開発のリアル - Speaker Deck
伊藤直也
株式会社一休 / CTO
Domain Modeling Made Functional
DDDを関数型でやってみる話
ドメインオブジェクトに型をいっぱい書きましょう
Union型を積極利用する
書籍通りにはやってない
Repositoryパターンは不要→なぜ?
ドメインオブジェクトは型で構造を定義
interface
オブジェクトの変更は関数適用による状態遷移でイミュータブルにする
ここを突き詰めると関数型プログラミング
命令的なものではない
customer.archive()ではなくconst archived = archiveCustomer(customer)
状態の変化が明示的になる
遷移前の状態は引数
遷移後の状態は戻り値
ユースケースはworkflowとして実装
入力値とドメインオブジェクトがドメインイベントに伴い新しい状態に遷移
Result型がないのでnerverthrowを使用
https://github.com/supermacro/neverthrow
値オブジェクトはコンストラクタで生成して失敗した場合はResultで返す
Railway Oriented Programming
TypeScript開発にRailway Orientedを持ち込み、より型安全なエラーハンドリングへ - Sansan Tech Blog
データベースIOはRepositoryパターン
Prismaでデータ取得してくるだけ
例外の場合はResultで受け取りたい
関数型でやっているのはドメイン層なだけ
それ以外は従来通りの作り
手続き型
全体はオニオンアーキテクチャ
Repositoryから取得するのがI/O境界
これをやりたいがためのアーキテクチャ
なぜ関数型スタイルにしたいのか
型を有効活用したい
静的検査で動かさないとわからないことが減る
オブジェクトの変更を「関数適用による状態遷移」にすると型を記述しやすい
すべてが明示的になる
失敗による分岐はResult型
I/O分離をするのが重要
そこから手続き型にないやすい
ドメインレイヤーを関数型にする余地が生まれる
Result型だけ面倒
パズルが増えてくる
値はだいたいResultに入ってるため
複数Resultがあると合成してフラットにする必要があって面倒・・・
それはそれで堅牢ではある
複雑なビジネスルールに挑む:正確性と効率性を両立するfp-tsのチーム活用術
複雑なビジネスルールに挑む:正確性と効率性を両立するfp-tsのチーム活用術 / Strike a balance between correctness and efficiency with fp-ts - Speaker Deck
kosui
株式会社カケハシ / テックリード
tRPCを実務に導入して分かった旨味と苦味
tRPCを実務に導入して分かった旨味と苦味 - Speaker Deck
海老原 圭吾
株式会社ゼスト 開発本部 / エンジニア
tRPCとは
TypeScript+RPC
Procedureのinput/outputの方をコード生成無しでクライアントに共有
2024-05-11時点でv11 bataが公開中
AppRouter typeでServer側に型導出する
型に関するGraphQLとの比較
GraphQL
スキーマ中心にそれぞれにコード生成
ClientがServerに依存していない
tRPC
ClientがServerに依存
Data Transformer
シリアライズ・デシリアライズを行う
デフォルトはJSON.stringify, JSON.parse
実装者自身で変更可能
superjsonでJSONにメタ情報を付与
plainではないオブジェクトも復元が可能
この表現力次第で柔軟に値や型が使用できる
値が単純にシリアライズ可能な型をカスタマイズせずとも使える
データ量にたいしてメタ情報分のデータが増える
1/4がメタ情報になる
パフォーマンス影響あり
対策
outputはサイズ重視で実装
inputはデータ量が大きいのでデバッグのしやすさとのトレードオフ
型ガード関数と同じで嘘を付くと型と簡単にズレていく
こういうのは型検査で防ぐことはできないのでUTを書く必要がある
アダプター
パッケージ単体はサーバーの機能は提供していない
Express, Fastify, Next.jsの上に乗せる
シンプルなスタンドアローンのものもある
旨味
一部だけtRPCにすることもできる
tRPCになう機能を土台となるアプリケーション機能で補える
フォームデータ
ファイルダウンロード
苦味
フォームデータを扱うのはまだexperimental
ルートに近いところで設定するのでContent-Typeに対応できる構造になってない
tRPCに得意なことをやらせるのが吉
なぜ採用したのか?
組織としてサーバーとフロントと横断できるようにしたかった
リソース配分を最適化しやすくする
Full TypeScriptでやっていく
Modelは共有しない
サーバーサイドとクライアントとでアクセスできるものが違う
コンポーネント自身でリクエストを叩く構造にシフトしてる
サーバーサイドでの型の複雑さがクライアントサイドに伝播する
Zodで複雑なデータ構造を定義するために工夫すると生成される型がより複雑になる
IDEが重くなってしまう
そのModelを元に作ったOutputがクライアントに渡る
リポジトリ構成
サーバーのパッケージをクライアントから参照できるようにする
リアルタイムで型が共有されるようになる
モノレポにしてyarn workspaceで管理
workspace沼にはまりやすくあまり活用できてない
サーバーの定義を買えるとその場でクライアント側で型エラーになる
サービス開発におけるVue3とTypeScriptの親和性について
サービス開発におけるVue3とTypeScriptの親和性について - Speaker Deck
からころ
株式会社LIXIL Marketing DevOps. System Dev. & Ope. Digital / アプリケーションエキスパート
親和性とは?
型付け+論理構成=親和性
TypeScriptとGraphQLで実現する型安全なAPI実装
Kazuhito Hokamura(hokaccha)
ユビー株式会社 / ソフトウェアエンジニア
TypeScriptとGraphQLで実現する 型安全なAPI実装 / TSKaigi 2024 - Speaker Deck
TypeScriptとGraphQLで実現する型安全なAPI実装
response.json()がanyなので渡ってくるものは祈ることになる
外部I/Oにおける片付けが不十分だと静的型付けの恩恵を得られない
APIに型をつけるとは?
スキーマで定義
仕様が定まってない場合はゆるふわになりがちなので定義していく
実装言語の方を自動で生成
手書きするとミスが発生する
生成された型で実装
GraphQLで型を付ける
型を付けるならgRPCが一番筋が良い
GraphQL Codegen
クライアントサイド
Client Preset
クエリから生成した型を使うのが重要
スキーマからだとすべての型情報をもってしまうので、undefinedになる可能性がある
TypedDocumentNode
クエリの型付きAST
クライアントに食わせると型が付く
Apollo Client
urql
graphql-request
Fragment Colocation
すべての末端コンポーネントまでトップレベルがクエリが知っている必要がある設計の歪を解消する
GraphQLにはfragmentという機能がある
定義を継承してくれる
Fragment Masking
自身で定義したfragmentの型をほかで使えないようにする
useFragment
第2引数のオブジェクトを返すだけの関数
型が複雑になるデメリットがある
サーバーサイド
TypeScript Resolvers
Server Presetは癖が強め
graphql-js
Apollo Server
GraphQL Yoga
NestJSのGraphQL Resolver関数を型安全にしたい
NestJSは特殊
Field Resolverを設定する
mappersでResolverの型を設定して使用する
Prettierの未来を考える
TSKaigi 2024 Prettierの未来を考える スピーカーノート
SosukeSuzuki
ユビー株式会社 / ソフトウェアエンジニア
Prettier Creator: James Long
JSXではなくhyperapp記法でReactを書いていた人
Prettier co-creator: Vjeux
Meta, Inc.所属、React Native関連の人
課題点
使い勝手の悪い点
単体で使う分は楽
設定は不要なので
ESLint等と組み合わせて使われることがある
Prettierはリンターの機能はない(責務ではない)
昔はフォーマットするルールもあった
衝突する場合にルールを変更する必要がある
esling-plugin系を組み合わせてやっていた
ESLintはデフォルトでTypeScriptをサポートしてない
実行速度が遅い
VSCodeで保存時にフォーマットする
これはそこまで問題ない
行数が膨大なのは若干カクつく
CLIでのユースケース
こういうのは遅い
Deno
deno lintとdeno fmtは設定無しで実行できる
fmtに採用されたコードフォーマッター dprint
Biome
元はRome
現代のフロントエンドツール設定がめんどい・しんどいのでそれを統一したい
npm i -D @biomejs/biome
npx @biomejs/biome init
未来のPrettierについて考える
アルゴリズム
Biomeと一緒
パフォーマンス(単一)
Biomeが速い
改善するための難易度は高い
パフォーマンス(複数)
Biomeのが速い
劇的に改善はできそう
早くしようとしてなかっただけ
パフォーマンス改善の余地あり
10倍早くできそう(現在改善中)
まだ足りない
リンターとのインテグレーション
そもそもBiomeはLinterを持ってる
なんらかラッパーをもつかscaffoldingが必要かも
ESLintとのインテグレーション
どっちも面倒
独自のESLint使いこなしているのはよりしんどい
サポート言語
Prettierが圧倒的
パーサーが各言語で使える
Biomeはパーサーを1から書いている
依存をさせたくないため
プラグイン
Biomeは計画中
GritQL integration progress (April 3) · biomejs biome · Discussion #2286 · GitHub
PrettierはJSで書ける
記述された言語
Biome: Rust
Prettier: JavaScript
最終的にどういう形で配布されるかの違いもある
多言語化対応における TypeScript の型定義を通して開発のしやすさについて考えた
多言語化対応における TypeScript の型定義を通して開発のしやすさについて考えた / TSKaigi TypeScript Multilingualization - Speaker Deck
nabeliwo
株式会社SmartHR / エンジニア