WorryFree Computers »
Address
:
[go:
up one dir
,
main page
]
Include Form
Remove Scripts
Accept Cookies
Show Images
Show Referer
Rotate13
Base64
Strip Meta
Strip Title
Session Cookies
Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Real World Type Puzzle and Code Generation
Search
Yuku Kotani
May 11, 2024
Technology
4
700
Real World Type Puzzle and Code Generation
TSKaigi 2024
https://tskaigi.org/
Yuku Kotani
May 11, 2024
Tweet
Share
More Decks by Yuku Kotani
See All by Yuku Kotani
Capacitor製のWebViewアプリからReact Native製のハイブリッドアプリへ
yukukotani
4
730
Kuma UI が提唱する Hybrid Approach CSS-in-JS の仕組み
yukukotani
2
340
GraphQLスキーマ設計の勘所
yukukotani
39
16k
既存Webサービスのモバイルアプリ版を 1週間でリリースし、進化させてきた話
yukukotani
0
590
先を見据えたMVPのフロントエンド開発
yukukotani
0
240
Bundle Side Optimization in Future JavaScript - JSConf JP 2021
yukukotani
2
2.7k
Kotlin/JS の仕組み / How KotlinJS works
yukukotani
5
2.9k
Kotlin/JS イケイケフロントエンド開発 / Ikeike Frontend Development in KotlinJS
yukukotani
0
340
Other Decks in Technology
See All in Technology
Unified Diff 形式の差分から Go AST を構築して feature flag を自動計装する
biwashi
7
660
筋トレ会社説明会【元パーソナルトレーナーが筋トレ/ダイエットメソッドを大公開】
yasumuusan
0
360
オブザーバビリティ勉強会で模擬障害対応をやってみた
leveragestech
1
180
CyberAgent AI事業本部2024年度MLOps研修実践編 / MLOps Practice
hosimesi11
4
5.5k
Reactのuse()って何なん?
diggymo
1
720
Luupの開発組織におけるインシデントマネジメントの変遷
grimoh
2
280
Dompter le chaos de l'information : Construire un Allié IA avec Langchain4J
magnette
0
120
Improve developer experience with Spring Interface Clients Spring I/O 2024
olgamaciaszek
0
160
When Walking like SREs
maruloop
3
650
TypeScripterに送るIaCの世界への招待〜AWS CDKと共に〜/inviting-typescripters-to-the-world-of-iac-with-aws-cdk
tomoki10
0
390
go get で考慮している ファイルシステムの挙動について
shinnosuke_kishida
3
370
Practices_for_improving_freee_development_productivity
hikarumiyazawa
0
190
Featured
See All Featured
Music & Morning Musume
bryan
42
5.7k
Scaling GitHub
holman
457
140k
YesSQL, Process and Tooling at Scale
rocio
165
13k
Creatively Recalculating Your Daily Design Routine
revolveconf
213
11k
The Cost Of JavaScript in 2023
addyosmani
24
4k
The World Runs on Bad Software
bkeepers
PRO
61
6.9k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
5
220
Adopting Sorbet at Scale
ufuk
69
8.7k
ParisWeb 2013: Learning to Love: Crash Course in Emotional UX Design
dotmariusz
104
6.7k
Web development in the modern age
philhawksworth
203
10k
How GitHub Uses GitHub to Build GitHub
holman
471
290k
Six Lessons from altMBA
skipperchong
22
3.1k
Transcript
Real World and Type Puzzle Code Generation @yukukotani 2024/05/11 -
TSKaigi 2024
小谷 優空 - @yukukotani ・Software Engineer @ Ubie, Inc. (2019/05~)
・Lead Architect ・Maintainer of Kuma UI ・Student @ Univ. Tsukuba (2019/04~) ・情報科学類 自己紹介
趣旨 型安全なコードを吐くコードジェネレータを作る野暮用があった(あるある) → 型安全 + コードジェネレータ = → 観察してエッセンスを抽出しよう! Prisma
観察するスキーマ このスキーマから生成されるコードを観察する User と Post がリレーションを持つ簡単なやつ
型パズルでselectした値に型をつける
None
None
簡略化した実装を観察する これが動くPrismaClient型(findFirst関数)の実装 スキーマに即した型がつく TS Playground
PrismaClient型 実際はクラスとして実装されているが、ここではシンプルなオブジェクト型に
入力の型を得る Type Argument Inferenceによって 型引数Tが推論される
入力の型を得る 型引数の制約は入力時の補完・エラー用。 GetSelectIncludeResultの導出には 条件型を使うので無関係
入力の型を得る 型引数の制約は入力時の補完・エラー用。 GetSelectIncludeResultの導出には 条件型を使うので無関係
出力の型を導出する 続いて出力の型を組成する要素を見ていく
$XxxPayload型 スキーマのモデルと対応して生成される カラムの型や他モデルとのリレーションを表現 → select結果の型を決定するための マスタとして機能 schema.prisma 生成される型
出力の型を導出する 第2型引数には入力の型をそのまま渡す
出力の型を導出する いよいよ出力の型そのものを見ていく
GetSelectIncludeResult<P, A> 事前生成のPayload型(P)とユーザーが渡す引数(A)から、select結果の型を導出
GetSelectIncludeResult<P, A> 条件型 `T extends { foo: infer S }
? S : never`パターンで、selectした中身を取る
GetSelectIncludeResult<P, A> Mapped Types で型を組み立てる
GetSelectIncludeResult<P, A> selectしたキーを Mapped Types のキーとする
GetSelectIncludeResult<P, A> キーに対応する値がfalse等の場合はneverにキャストして除外 Mapped Typesのキーを neverにすると丸ごと消える
GetSelectIncludeResult<P, A> Mapped Typesの値側を見ていく
GetSelectIncludeResult<P, A> Payload型を参照して、selectする値の型を取る
おさらい:$XxxPayload型 select結果の型を決定するためのマスタ schema.prisma 生成される型
GetSelectIncludeResult<P, A> scalarsではなくobjectsの場合も同様に取り、再帰的にselect結果を導出
GetSelectIncludeResult<P, A> 条件型に当てはまらなければneverに落とすが、最初の型制約で先に落ちるはず
まとめ:型パズルのエッセンス 型パズルを要素分解すると組み立てやすq Uf 型引数の推論によって入力の型を得 Df 型引数の制約を につけ E インターナルな型引数は補完不要なので頑張らなくて良q Bf
入力の型を条件型で絞り込みながら出力の型を組み立て E 事前生成したマスタ型(Payload)を参照してシンプル化 入力時の補完・エラーのため
型パズルをできるだけ頑張らない
なるべく事前生成して型計算を避ける Payload型から型パズルで導出できそうだが 重複を許容してすべて静的にコード生成する
なるべく事前生成して型計算を避ける モデルの一般化もせず重複生成
なるべく事前生成して型計算を避ける 事前生成ファイルは基本編集しないので、パースコストの影響が限定的 → ファイルサイズが大きくなってもOK 型チェックはfindFirstとかを触るたびに発生する(tsc内部でキャッシュは効くが) → パフォーマンスがDXに直撃する さらにビルド時間でもパースに比べて型チェックのほうが影響が大きい prisma/prisma の
tsc trace パース時間 型チェック時間
なるべく事前生成して型計算を避ける リアルタイムな入力に対してフィードバックしたい部分に絞って型計算をする その他はできるだけ静的にコード生成する
コード生成もできるだけ頑張らない
None
None
コード生成するコードは基本的につらい テンプレートリテラルなりASTビルダなりで組み立てるので見通しは最悪 なるべく生成するパターンを減らしたい
ライブラリとして切り出す 生成するコードのうち静的な部分はライブラリに切り出して、 生成コードからは参照するだけ 生成したコード
ライブラリとして切り出す Tips: ライブラリ内で使っているinternalな型もすべてexportする exportしていないと、この型を参照する他パッケージの.d.tsに インライン化されて爆発する Ref: https://github.com/prisma/prisma/blob/main /packages/client/src/runtime/core/types/exported/README.md
型以外は生成しない 生成された .d.ts 3500行に対して .js は200行程度 コード生成で頑張るのではなく Proxy を使った動的操作をしている
まとめ H リアルタイムな入力にフィードバックしたい部分だけは型パズルを頑張5 H 型パズルを要素分解して順番に考えるとやりやすF H それ以外はコードの重複を許容して事前生成に振り切5 H 完全に静的な型は生成すらせずライブラリÆ H
型以外のランタイム処理はProxyで頑張る
Thanks! Ubieのブースにいます!