Slide 1

Slide 1 text

2025.05.23 | TSKaigi 2025 | @progfay 高 度な型付け、どう教える?

Slide 2

Slide 2 text

Name: 眞野 隼 輔 ま の しゅんすけ    @progfay ・ Web Frontend Engineer ・ 普段は Web の動向を追っかけている ɾ型パズルは独学で習得 🧩

Slide 3

Slide 3 text

今 日 は「 高 度な型付けの教え 方 の提案」をします

Slide 4

Slide 4 text

発表の想定対象者 高 度な型付けを 「教える」 人 向け ✅ ⚠「学ぶ」 人 向けではない ❌

Slide 5

Slide 5 text

・ 以下などを組み合わせて型を作ること ɾGenerics: Hoge ɾConditional Types: T extends U ? A : B ɾMapped Types: { [K in keyof T]: string } ɾRecursive Types ・ 特に「理解や実装が難しいもの」を指す 高 度な型付け とは

Slide 6

Slide 6 text

・ 型の恩恵を得るためには、 高 度な型付けをしたいときが稀にある ・ 高 度な型付けは誰でも読み書きできるものではない ・ メンバーが理解できないコードは負債になる 高 度な型付けを教える必要はあるのか? 諦める? or メンバーにも書けるようになってもらう!

Slide 7

Slide 7 text

1 . 書き 手 が処理の流れをイメージしづらい • 初 手 で型レベルプログラミングの 心 理的 ・ 技術的ハードルが 高 い 2 . debug がしづらい • 一 時変数や console.log が使えない 3 . TypeScript の挙動に癖がある • Distributive Conditional Types • (() => {}) extends Record ? true : never 高 度な型付けの課題

Slide 8

Slide 8 text

提案 ɹ で「下書き」→ ɹ に「翻訳」 慣れ親しんだ 言 語で処理の流れを把握して 型レベルプログラミングに置き換えていく

Slide 9

Slide 9 text

「下書き」の恩恵 ・ 心 理的ハードルを下げられる ・ 処理や思考の整理ができる ・ debug が可能になる

Slide 10

Slide 10 text

「翻訳」

Slide 11

Slide 11 text

• JS ⁶ TS は完全には対応しない • optional property や readonly, Union は JS でどう表現する? • 生 徒が困らないよう、教師が場を整えてあげる必要がある • TypeScript 特有の癖はそのまま • JS → TS に変換したら謎の挙動になることもある • 体当たりで学ぶ or TypeScript ͷ࢓༷ΛֶͿඞཁ͕͋Δ 「翻訳」の注意点

Slide 12

Slide 12 text

1 . JavaScript で「下書き」 2 . TypeScript に「翻訳」 3 . 意図通りの型付けができているか確認する 4 . 上 手 くいくまで 1 ~ 3 を繰り返す 高 度な型付けの流れ

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

「下書き」のための Helper

Slide 15

Slide 15 text

deepReadonly(t)

Slide 16

Slide 16 text

deepReadonly(t) → DeepReadonly

Slide 17

Slide 17 text

deepReadonly(t) → DeepReadonly

Slide 18

Slide 18 text

deepReadonly(t) → DeepReadonly

Slide 19

Slide 19 text

deepReadonly(t) → DeepReadonly

Slide 20

Slide 20 text

deepReadonly(t) → DeepReadonly

Slide 21

Slide 21 text

deepReadonly(t) → DeepReadonly

Slide 22

Slide 22 text

deepReadonly(t) → DeepReadonly

Slide 23

Slide 23 text

DeepReadonly

Slide 24

Slide 24 text

DeepReadonly なぜ?🤔

Slide 25

Slide 25 text

Function は Record の sub type → Mapped Types に 入 れると {} になる TypeScript 特有の癖

Slide 26

Slide 26 text

deepReadonly(t) を改良

Slide 27

Slide 27 text

DeepReadonly

Slide 28

Slide 28 text

DeepReadonly

Slide 29

Slide 29 text

DeepReadonly 🎉🎉🎉

Slide 30

Slide 30 text

• 対象: 高 度な型付けに馴染みのないエンジニア 3 名 • 形式: ペアプロ形式で DeepReadonly を書く • 結果: 20 分ほどで書けた! • 感想: • 従来の課題だった「最初から型レベルプログラミング」が解消されていた! • 再帰処理の実装は不慣れだったが、debug しながらだったので何とか書けた • この形式で何度か経験を積めば、書けるようになるかも? 実践してみた

Slide 31

Slide 31 text

良いところ👍 と 悪いところ👎 を振り返ろう しかし万能な 手 法ではない

Slide 32

Slide 32 text

なんか変なのいるぞ...? 「下書き」のための Helper 再 掲

Slide 33

Slide 33 text

• JS での「下書き」ができればいい • configurable: false にしなくていい • ただし書き味にはこだわりたい • テスト可能にしたい JS ͷ readonly を TS の書き味に近づけたい

Slide 34

Slide 34 text

No content

Slide 35

Slide 35 text

readonly(t[key]) と書くためには __readonly property を 生 やす

Slide 36

Slide 36 text

• string literal (property が 生 やせない) • "str" • String("str") • String object (property が 生 やせる!) • new String("str") 👎 学びやすい Helper 関数を 用 意するのが難しい

Slide 37

Slide 37 text

👍 慣れ親しんだ 言 語で書き出せる 👍 debug できる 再 掲 deepReadonly(t)

Slide 38

Slide 38 text

deepReadonly(t) → DeepReadonly 👎 JS → TS の翻訳が 自 明ではない 再 掲

Slide 39

Slide 39 text

DeepReadonly 👎 TypeScript 特有の癖は残る 再 掲

Slide 40

Slide 40 text

👍「下書き」に戻って考え直せる 再 掲 DeepReadonly

Slide 41

Slide 41 text

• 良いところ👍 • 慣れ親しんだ 言 語で書き始められる • debug できる • 「下書き」に戻って考え直せる • 悪いところ👎 • 学びやすい Helper を 用 意するのが難しい • JS → TS の変換が 自 明ではない • TypeScript 特有の癖は残る } 生 徒が学びやすくなる } 教師の下準備や教え 方 が難しい

Slide 42

Slide 42 text

下準備を AI にやらせてみた • DeepReadonly で one-shot prompting • PickByType を JavaScript の「下書き」に 変換してもらった

Slide 43

Slide 43 text

下準備を AI にやらせてみた

Slide 44

Slide 44 text

下準備を AI にやらせてみた 下準備の難しさを緩和できそう!

Slide 45

Slide 45 text

• 問題: 高 度な型付けは処理の流れがイメージしづらく、 debug もしづらい • 提案:   で「下書き」→   に「翻訳」 • 実演: DeepReadonly を例に教え 方 の流れを説明した • 評価: 教師の下準備の難易度が 高 いが、 生 徒は 比 較的学びやすい • 展望: AI に下準備をさせることで、教師の負担を減らせそう! • 今後: 現場で 高 度な型付けが必要になったら、またこの 手 法使ってみる予定 まとめ

Slide 46

Slide 46 text

• Deep Readonly · type-challenges/type-challenges - GitHub • DeepReadonly を教えるサンプルプログラム - TypeScript Playground • AI に TS の「型定義」→ JS の「下書き」変換をさせる - Gemini リンク集