Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
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
980
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
一億総業務改善を支える社内AIエージェント基盤の要諦
yukukotani
8
3k
MCPとデザインシステムに立脚したデザインと実装の融合
yukukotani
6
2.4k
Scale out your Claude Code ~自社専用Agentで10xする開発プロセス~
yukukotani
10
4.7k
AI Coding Agent Enablement in TypeScript
yukukotani
21
14k
AI Coding Agent Enablement - エージェントを自走させよう
yukukotani
14
8k
Expoによるアプリ開発の現在地とReact Server Componentsが切り開く未来
yukukotani
3
750
React 19でお手軽にCSS-in-JSを自作する
yukukotani
6
960
僕が思い描くTypeScriptの未来を勝手に先取りする
yukukotani
12
3.4k
Web技術を駆使してユーザーの画面を「録画」する
yukukotani
14
8k
Other Decks in Technology
See All in Technology
「図面」から「法則」へ 〜メタ視点で読み解く現代のソフトウェアアーキテクチャ〜
scova0731
0
310
【AWS re:Invent 2025速報】AIビルダー向けアップデートをまとめて解説!
minorun365
4
530
RAG/Agent開発のアップデートまとめ
taka0709
0
180
AI-DLCを現場にインストールしてみた:プロトタイプ開発で分かったこと・やめたこと
recruitengineers
PRO
2
150
ガバメントクラウド利用システムのライフサイクルについて
techniczna
0
190
AWSセキュリティアップデートとAWSを育てる話
cmusudakeisuke
0
290
文字列の並び順 / Unicode Collation
tmtms
3
600
AI駆動開発における設計思想 認知負荷を下げるフロントエンドアーキテクチャ/ 20251211 Teppei Hanai
shift_evolve
PRO
2
420
AIプラットフォームにおけるMLflowの利用について
lycorptech_jp
PRO
1
170
生成AI活用の型ハンズオン〜顧客課題起点で設計する7つのステップ
yushin_n
0
230
Jakarta Agentic AI Specification - Status and Future
reza_rahman
0
110
会社紹介資料 / Sansan Company Profile
sansan33
PRO
11
390k
Featured
See All Featured
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
10
730
Practical Orchestrator
shlominoach
190
11k
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
Learning to Love Humans: Emotional Interface Design
aarron
274
41k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
249
1.3M
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
55
3.1k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
9
1k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
1.6k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
Optimising Largest Contentful Paint
csswizardry
37
3.5k
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.3k
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のブースにいます!