Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Zodのデータ変換が便利すぎた。 しかし使いすぎで苦しくなっていった話
Search
Melonps
May 09, 2026
Technology
93
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Zodのデータ変換が便利すぎた。 しかし使いすぎで苦しくなっていった話
フロントエンドカンファレンス名古屋のLT登壇資料です。
Melonps
May 09, 2026
More Decks by Melonps
See All by Melonps
コーディングエージェントはTypeScriptの 型エラーをどう自己修正しているのか
melonps
4
840
さくらのAI Engineから始める クラウドネイティブ意識
melonps
0
350
15年続くIoTサービスのSREエンジニアが挑む分散トレーシング導入
melonps
2
780
OpenTelemetryで“見えるIoT”を目指したら クラウドネイティブの奥深さに直面した
melonps
0
100
LangChainについてのサーベイ
melonps
0
230
CloudSeed
melonps
0
200
Other Decks in Technology
See All in Technology
AI時代のPRレビューにどう向き合うか?
kairim0
1
210
AI時代だからこそ推したい!Gitコマンド再入門
munakata
0
180
ハードウェアコンペでもAI駆動開発が進んでいる話
iotengineer22
1
690
パッチ更新でterraform initが落ちた日
grimoh
1
120
メルペイ 会計システム概要と歴史
mewuto
1
210
⾮構造化データを価値に変える AI エージェント基盤とその組織
ivry_presentationmaterials
0
140
全PRの83%が AIレビューだけでマージできるようになった開発組織は その後どうなったか @2026/10
athug
0
140
Essential architectural thinking (revised edition)
ufried
0
110
宣言型部分更新は何を解決しどこへ向かうのか
shuta13
1
320
V8のArray.prototype.flatを最大約20倍速くするまでと、巨大OSSへの大規模コミットの道のり
riyaamemiya
0
270
事業成長とデータ活用を止めないためのマネジメントへ挑戦
hiracky16
0
300
子育てエンジニアの可処分時間が減っても成長を諦めない戦い方
sudoakiy
6
4.5k
Featured
See All Featured
Measuring & Analyzing Core Web Vitals
bluesmoon
9
1k
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
2
2.9k
Reality Check: Gamification 10 Years Later
codingconduct
0
2.3k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
56
3.5k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
1.1k
The untapped power of vector embeddings
frankvandijk
2
1.9k
Into the Great Unknown - MozCon
thekraken
41
2.8k
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
1
280
Thoughts on Productivity
jonyablonski
76
5.4k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
360
VelocityConf: Rendering Performance Case Studies
addyosmani
331
25k
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
520
Transcript
Zodのデータ変換が便利すぎた。 しかし使いすぎで苦しくなっていった話 パナソニック エレクトリックワークス株式会社 筧 万里 1 フロントエンドカンファレンス名古屋 2026 LT
自己紹介 2 BANRI KAKEHI(@Melonps_) ◦ 家庭用燃料電池「エネファーム」のSRE ◦ クラウドネイティブ会議実行委員 ◦ Yamada
UIのメンテナー エネファーム
スキーマ定義にどこまで書くか? ◎Zodで型定義とバリデーションと両立させて使う形が多い 3 const UserSchema = z.object({ name: z.string(), age:
z.number().min(0), email: z.email(), }); const result = UserSchema.safeParse({ name: "太郎", age: 1000, email: "
[email protected]
", }); console.log(result.success, result.data) スキーマ定義(TS) パースによるランタイムでの検証 APIレスポンスの検証やフォーム入力制御で活躍
データ変換ツールとしても進化してきた .transform():バリデーション後に型変換 4 const NameLengthSchema = z.string().transform((val) => val.length); type
Input = z.input<typeof NameLengthSchema>; type Output = z.output<typeof NameLengthSchema>; .pipe():変換後の値に再バリデーション const SafeStringToNumber = z.string() .transform((value) => Number(value)) .pipe(z.number().min(0).max(100)); numberが確定 0~100が確定
何でこれが苦しくなるの? 5 データ変換を使い倒して 便利だった実装と苦しくなっていった実装
便利だった 便利だった実装:APIレスポンスの入り口 6 const EventSchema = z.object({ startAt: z.iso.datetime().transform((val) =>
new Date(val)), endAt: z.iso.datetime().transform((val) => new Date(val)), }).refine((data) => data.endAt.getTime() > data.startAt.getTime(), { message: "終了時刻は開始時刻より後に設定してください", path: ["endAt"], }); ◎APIから得たデータの論理と型の検証をする 論理の保証 ルールの整備がないままtransform化が進んでいった Date型へ変換
苦しくなった const EventSchema = z.object({ startAt: z.iso.datetime().transform((val) => new Date(val)),
endAt: z.iso.datetime().transform((val) => new Date(val)), attendees: z.array(z.object({ name: z.string(), role: z.string() })), }).transform((event) => ({ ...event, duration: event.endAt.getTime() - event.startAt.getTime(), activeAttendees: event.attendees.filter((a) => a.role !== "observer"), })); 苦しくなっていった実装 7 ◎データクレンジングや表示用の変換を持ち始めた →スキーマを追加するごとに、テストや議論が必要な状態に... 表示用の変換 useFormに渡す型はIn?Out? フィルタリング
どうすれば良かったのか? 8 ビジネスロジック ◎外部の不確実性から守るため、スキーマを境界の入り口とするべき ◦ 複数の境界をまたぐ変換は不適切 ◦ 同じ境界の中であれば、関数に切り出すべき Functional Core
Mutable Shell
こう整理して挑戦中です 9 ◎スキーマを定義する前のチェックリスト リファクタ案やブランド型の話もしたかった... ◦ ①:「何と何の境界」を担っているか説明できるか? ◦ ②:外→内への境界か、内→内への境界か?(後者なら関数に切り出す) ◦ ③:一つだけの境界を対象としているか?
ご清聴ありがとうございました!
None