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
TSKaigi Night Talks 2026_TypeScriptでサプライチェーンの整合...
Search
ギークプラス ソフトウェア事業部
June 10, 2026
Programming
400
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
TSKaigi Night Talks 2026_TypeScriptでサプライチェーンの整合性を型に閉じ込める
2026/06/10開催のTSKaigi Night Talks 2026の登壇資料
ギークプラス ソフトウェア事業部
June 10, 2026
More Decks by ギークプラス ソフトウェア事業部
See All by ギークプラス ソフトウェア事業部
会社説明資料|株式会社ギークプラス ソフトウェア事業部
geekplus_tech
0
880
ソフトウェア事業部のビジョン
geekplus_tech
1
79
インフラを Excel 管理していた組織が 3 ヶ月で IaC 化されるまで
geekplus_tech
3
260
Other Decks in Programming
See All in Programming
LaravelLive Japan の裏方のすべて — 第188回 PHP勉強会@東京 (2026-06-24)
suguruooki
2
110
AIだと陥りがちなJakarta EE最新技術への移行時の落とし穴と解決策
tnagao7
0
120
セキュリティの専門家じゃなくてもできる。「セキュリティ意識」をアップデートして サプライチェーン攻撃への耐性を高めよう。
tk3fftk
5
920
Creating Composable Callables in Contemporary C++
rollbear
0
160
Performance Engineering for Everyone
elenatanasoiu
0
210
ふつうのFeature Flag実践入門
irof
8
4.2k
そのテスト、説明できますか?~LWテスト戦略FW~のご紹介
nakahara
0
160
Even G2とAWSで推しのエージェントを召喚しよう!
har1101
1
120
依存関係から依存物へ―Dependencyという言葉の歴史をひも解く
j_lee
0
130
Lessons from Spec-Driven Development
simas
PRO
0
220
AI 時代のソフトウェア設計の学び方
masuda220
PRO
29
13k
Vite+ Unified Toolchain for the Web
naokihaba
0
340
Featured
See All Featured
The Language of Interfaces
destraynor
162
27k
It's Worth the Effort
3n
188
29k
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
1
3.6k
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.3k
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
170
WCS-LA-2024
lcolladotor
0
650
RailsConf 2023
tenderlove
30
1.5k
HDC tutorial
michielstock
2
720
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
5
1.1k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
10k
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
320
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
65
56k
Transcript
Moving the world intelligently ©Geekplus Co., Ltd. TypeScriptで サプライチェーンの整合性を 型に閉じ込める
株式会社ギークプラス Soju Kameyama | Web Engineer 2026.06.10
Moving the world intelligently ©Geekplus Co., Ltd. 2 ⾃⼰紹介 ⽒名
⻲⼭ 創樹(Soju Kameyama) 所属 株式会社ギークプラス ソフトウェア事業部 経歴 株式会社インフォマティクス 入社 キヤノン株式会社 入社 KINTOテクノロジーズ株式会社 入社 株式会社ギークプラス 入社 2017 2019 2022 2026 サプライチェーンに関わるお客様の業務を支援するSkylaaの開発を行っています 担当
INDEX Moving the world intelligently ©Geekplus Co., Ltd. 3 1.
同じ事実を別々に持つと、ズレる問題 2. 発想を変えてみる:保存するのは"流れ"だけ 3. まとめ 今回はバックエンドのお話になります
Moving the world intelligently ©Geekplus Co., Ltd. 4 1. 同じ事実を別々に持つと、ズレる問題
設計で悩んだ部分です
「品切れ」が上へさかのぼる例で考える ④発注先の⼯場から納品 (⼯場 → 倉庫) 100個 ⑤⾃社倉庫からお店へ転送 (倉庫 → お店)
100個 ①お店の棚が100個 品切れ!! Moving the world intelligently ©Geekplus Co., Ltd. ②転送依頼 ③発注依頼 この場合のモノの動きは2種類 = 「外部から取り寄せる(発注系)」と「内部で移動(転送 系)」 ⾃社倉庫 取引先メーカー
同じ100個の動きを、別々の表で⾒たい さきほどの“⼀連の流れ” (⼯場→倉庫→お店 / 100個の動き) Moving the world intelligently ©Geekplus
Co., Ltd. 「⼯場への発注リスト(⼯場→倉庫 100)」 「お店への転送リスト(倉庫→お店 100)」 「『品切れをどう埋めたか』全体の流れ」
システムで単純に表現しようとするとこんな感じに 「発注リスト」を保存? 「転送リスト」を保存? 「全体の流れ」も保存? 流れ Moving the world intelligently ©Geekplus
Co., Ltd. → 3つを 別々に組み⽴てて、別々に持つ?? ?
Moving the world intelligently ©Geekplus Co., Ltd. 整合性が崩れる罠 • 「転送リスト」だけ直して他を直し忘れる
→ 発注リスト‧全体の流れとズレる • 表を増やすたびに、 整合チェックのコードも増える 同じ事実を個別に持つと、バグの温床に
Moving the world intelligently ©Geekplus Co., Ltd. 9 2. 発想を変えてみる:保存するのは"流れ"だけに
設計を⾒直しました
話を戻すと さきほどの“⼀連の流れ” (⼯場→倉庫→お店 / 100個の動き) 「⼯場への発注リスト(⼯場→倉庫 100)」 「お店への転送リスト(倉庫→お店 100)」 「『品切れをどう埋めたか』全体の流れ」
Moving the world intelligently ©Geekplus Co., Ltd. どれも同じ「1本の流れ」を別の⾓度で⾒ているだけ →保存するのも1つで良さそう
Moving the world intelligently ©Geekplus Co., Ltd. 発想を変えてみる:流れだけ保存して、表は計算する 保存するのは「流れ」だけで各リストは流れからの計算 =
Reactの「派⽣stateは持たず計算する」と同じで、状態は1つ+表⽰は計算 ⼯場 → 倉庫 → お店 「⼀連の流れ」(唯⼀の正解) 関数で計算 (保存しない) 発注リスト 転送リスト 全体リスト その他記録 保存するやつ 計算で出すやつ ※ 物の移動 物の移動 物の移動 物の移動 物の移動
使う道具は、主に2つ 判別可能ユニオン 「この変数は、何種類かのうちのどれか1つ」という型 type Shape = | { kind: 'circle';
r: number } | { kind: 'square'; size: number } // 種類によってプロパティ構成も変えられる 各種類に⾒分けるためのラベル(タグ)がある 純粋関数 同じ⼊⼒なら、必ず同じ出⼒(外の状態に触れない) const add = (a: number, b: number) => a + b // DB や グローバルオブジェクト には触らない 結果が予測できる → テストが楽、どこでも再利⽤できる この2つを⽤いて 「流れ → 表」 を安全に組み⽴てることができる Moving the world intelligently ©Geekplus Co., Ltd.
流れは、2種類のノードでできた“⽊構造”と捉える 外から取り寄せる(発注) 中で運ぶ(転送) // 流れの中の1ノード(2種類) type Node = | {
kind: 'order'; // 発注 // ...(プロパティは省略) children: Node[] // 次のノード } | { kind: 'transfer'; // 転送 // ...(プロパティは省略) children: Node[] // 次のノード } 「種類は2つのうち1つだけ(判別可能ユニオン)」を型で宣⾔(取り違えはコンパイルエラー) ※スライド⽤に名前を簡略化しています Moving the world intelligently ©Geekplus Co., Ltd.
流れは、2種類のノードでできた“⽊構造”と捉える ※スライド⽤に名前を簡略化しています Moving the world intelligently // ノード定義(流れの中の1ノードにあたり、今回は2種類用意) type Node
= | {kind:'order'; from:string;to:string;qty:number;children:Node[]} | {kind:'transfer'; from:string;to:string;qty:number;children:Node[]} // ①「流れ」をこういう入れ子のオブジェクトに格納(実際には DBから取ってくる) const flow: Node[] = [{ kind: 'order', from: '工場', to: '中央倉庫', qty: 180, children: [ {kind:'transfer',from:'中央倉庫',to:'渋谷店',qty:100,children:[]}, {kind:'transfer',from:'中央倉庫',to:'新宿店',qty: 80,children:[]}, ], },] // ② 木を歩いて、指定した kind のノードだけ集める関数(純粋関数) function collect(nodes: Node[], kind: Node['kind']): Node[] { return nodes.flatMap((n) => [ ...(n.kind === kind ? [n] : []), // ← unionだからkindで絞り込める ...collect(n.children, kind), ]) } // 上記関数を使って注文リスト・配送リストを作成(表示用) const orderList = collect(flow, 'order') // 工場→中央倉庫 const transferList = collect(flow, 'transfer') // 中央倉庫→各店舗
さらに拡張すると(卸売業者パターン) Moving the world intelligently ©Geekplus Co., Ltd. 発注 転送
転送 転送 転送 転送 出荷 出荷 出荷 出荷 複雑な⽊構造も1つの流れとして組み⽴てることができる • 外部の会社に持ち出す「出荷型」を新たにNode定義(内から外) • ⽊構造なので枝分かれも表現できる ex.外部⼯場から親倉庫へ ex.親倉庫から⼦倉庫Aへ ex.⼦倉庫から孫倉庫へ ex.孫倉庫から外部⼩売業者へ ex.親倉庫から⼦倉庫Bへ
Moving the world intelligently ©Geekplus Co., Ltd. 16 3. まとめ
もう少しだけお付き合いください
まとめ ⼀連の物の流れにおいて、状態は1つだけ(⽊構造として)持つようにする そこから派⽣する値は保存せずに計算(純粋関数)で出すようにする 「状態は1つ、表⽰は計算」 → 改修時にズレを直すのではなく起こさないようにする Moving the world intelligently
©Geekplus Co., Ltd.
Moving the world intelligently ©Geekplus Co., Ltd. 18 ありがとうございました
©Geekplus Co., Ltd.