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
僕が思い描くTypeScriptの未来を勝手に先取りする
Search
Yuku Kotani
September 06, 2024
Programming
3.6k
12
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
僕が思い描くTypeScriptの未来を勝手に先取りする
Web Developer Conference 2024
https://web-study.connpass.com/event/321711/
Yuku Kotani
September 06, 2024
More Decks by Yuku Kotani
See All by Yuku Kotani
Webとヘルスデータ
yukukotani
1
480
LLM本来の能力を解き放つサンドボックス技術とAI民主化への適用
yukukotani
3
5.4k
一億総業務改善を支える社内AIエージェント基盤の要諦
yukukotani
9
3.6k
MCPとデザインシステムに立脚したデザインと実装の融合
yukukotani
6
3k
Scale out your Claude Code ~自社専用Agentで10xする開発プロセス~
yukukotani
11
5.9k
AI Coding Agent Enablement in TypeScript
yukukotani
21
21k
AI Coding Agent Enablement - エージェントを自走させよう
yukukotani
14
8.6k
Expoによるアプリ開発の現在地とReact Server Componentsが切り開く未来
yukukotani
3
960
React 19でお手軽にCSS-in-JSを自作する
yukukotani
6
1.1k
Other Decks in Programming
See All in Programming
GraphRAGのKnowledge Graphを 直接!見る/View-GraphRAG's-KnowledgeGraph-directly!
tyumugi1113
1
300
AGENTS.md Is Not Enough:Build Skills, Don't Download Them
lx_t
0
110
初心者DevRelとして参加者だった私が、DevRel Talks!#2に登壇するまでにしてきたこと
sokohirai
0
370
AIとGame Jamで、ゲームを完成させた話
takahirosaeki
0
120
App Intentsのビルドプロセスを支える技術
kntkymt
0
330
Claude Codeを組織的に動かして月400PRを実現した話
happy_ryo
0
270
WebMCP Challenge に星空観察アプリで参加した話
okajun35
0
150
Jetpack Compose メカニズム
skydoves
0
320
XP祭りでしか伝わらないフリップネタ #xpjug
murabayashi
0
150
ゲームコントローラやキーボードのファームウェアをSwiftで書く
kishikawakatsumi
1
230
AI Agent時代のリアーキテクチャ戦略と実践
hokaccha
9
4.2k
cdk deploy JawsSonic #MARATHONしながらAWSリソースをデプロイしてみよう
akihisaikeda
2
110
Featured
See All Featured
The SEO Collaboration Effect
kristinabergwall1
1
560
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
287
14k
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
790
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
530
HTML-Aware ERB: The Path to Reactive Rendering @ RubyCon 2026, Rimini, Italy
marcoroth
4
640
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
63
46k
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
500
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
1
6.2k
From π to Pie charts
rasagy
0
360
Game over? The fight for quality and originality in the time of robots
wayneb77
1
270
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
1
480
Transcript
僕が思い描く 勝手に TypeScriptの未来を 先取りする @yukukotani 2024/09/07 - Web Developer Conference
2024
自己紹介 小谷 優空 - @yukukotani ・VP of Technology @ Ubie,
Inc. ・Maintainer of KumaUI ・Student @ Univ. Tsukuba
今日の趣旨 Call-this operatorが好きすぎて僕だけ勝手に使っている話を延々とします 自由研究とか図画工作の類です
Call-this operator、なんなんじゃそりゃ Function.prototype.call の糖衣構文となる二項演算子 TC39で提案中のStage-1プロポーザル NEW!
Function.prototype.call、なんなんじゃそりゃ 任意の値をthisに束縛して関数を呼べる → Call-this operatorだと できる レシーバをthisに束縛
Function.prototype.call、なんなんじゃそりゃ 任意の値をthisに束縛して関数を呼べる → Call-this operatorだと できる レシーバをthisに束縛 そんなの使ったことないよ
いろいろな Function.prototype.call G プロトタイプ汚染の防6 G 組み込み関数のモンキーパッQ G メソッドの動的切り替! G etc...
いろいろな Function.prototype.call G プロトタイプ汚染の防6 G 組み込み関数のモンキーパッQ G メソッドの動的切り替! G etc...
僕らはそんなことしないよ
では僕たちアプリケーション開発者 にとって何がうれしいのか?
(1) classの代替
よくあるclassベースのモデル 抽象クラスUserには2種2 G RegisteredUser, AnonymousUser 両方からリソースのURLを取れる RegisteredUserだけはメールを送れる
TypeScriptのclassには色々なつらみがある classのメソッドはシリアライズ/デシリアライズできない(当然) Next.jsのServer Actionsのような境界で壊れがち user2.getUrl is not a function
TypeScriptのclassには色々なつらみがある TypeScriptの構造的部分型ではclassの名前が無視される 全く同じプロパティを持っていたら別クラスでも型が一致してしまう https://example.com/articles/foo UserにArticle代入できちゃう Userと全く同じシグネチャ idとgetUrl
TypeScriptのclassには色々なつらみがある classのメソッドにはDead Code Eliminationが効かず、バンドルサイズ肥大化 メソッドが依存する外部ライブラリ等のTree Shakeも芋ずる式に効かなくなる このメソッドは未使用なのに ビルド成果物に残ってしまう
TypeScriptのclassには色々なつらみがある そもそもclass一般の話題として、継承によるモデリングの限界も見えてきている https://speakerdeck.com/naoya/guan-shu-xing-puroguramingutoxing-sisutemunomentarumoderu?slide=54
人々はtypeと関数に救いを求めた G 振る舞いは純粋な関数として実8 G データはただのtypeとして定& G Tagged Unionで多態相当の表現
type+関数が結論なのか!? データはただのオブジェクトなのでシリアライズ・デシリアライズできる エラーにならない!
type+関数が結論なのか!? Tagged Unionのようにタグを付けておけば異なる型をちゃんと区別できる 発展的には Branded Type のようなテクニックもある エラー!kindが異なるので代入できない
type+関数が結論なのか!? Dead Code Elimination も当たり前に効く 未使用なので関数丸ごと消える
type+関数が結論なのか!? いいことづくしなのにclassを使い続ける人が多いのはなんでだろう
classのここが嬉しい! データに対する振る舞いが閉包的に定まる 普通に書けばデータそのものが振る舞いの名前空間となるから(prototype) userに対する振る舞いは getUrl, sendEmailに定まる
classのここが嬉しい! より直接的に言うと、レシーバを書いた時点でその振る舞いがわかる
type+関数だとメンタルモデルが異なる 関数ベースだと、まずグローバルな名前空間から振る舞いを探す必要がある (名前空間のためにオブジェクト作ったりするとTree Shakeできなくなる)
それ、Call-this operator でできるよ! レシーバにしたい型を This Parameter で定義 普通の引数の代わりに thisの型を定義
それ、Call-this operator でできるよ! 型が名前空間として機能し、 データ→型→振る舞い という紐付きで同定できる ~> を打ったタイミングで レシーバとThis Parameterを型検査
マッチするものだけ取り出せる
DEMO
(2) Tree Shake可能なユーティリティ
僕たちも嬉しい Call-this operator メソッドチェーンのDXとツリーシェイク可能なインポートの両立 zodとvalibotの良いとこ取りみたいなことができる 体験は良いけど Tree Shaking効かない 補完体験を維持しつつ Tree
Shakingも効く! Tree Shaking効くけど 補完体験が悪い
DEMO
よさそうなことはわかった 使いたい
Call-this operator、なんなんじゃそりゃ Function.prototype.call の糖衣構文となる二項演算子 TC39で提案中のStage-1プロポーザル NEW!
TC39? Stage 1? ECMAScriptの仕様を議論する委員会。仕様提案をStageに分けて管理している Stage 0 新しく提出されたプロポーザル。まだTC39の議論対象ではない Stage 1 Championと呼ばれる推進者が決まり詳細化されたプロポーザル。TC39の議論対象になる
Stage 2 セマンティクスや文法といった仕様の草案が定義され、その方向性に合意したプロポーザル Stage 2.7 仕様が決定し、原則承認されたプロポーザル。実装上の不都合がないかテストやプロトタイピングで検証する Stage 3 本番での実装が推 奨されるプロポーザル。実 世界で不都合がないか フィー ドバック を集める Stage 4 正式に承認されたプロポーザル。 ここか ら変更は 入らず、 次バー ジョンの EC MAScrip tに 含まれる
Babelプラグインで試したい Stage3以前の構文系の提案はBabelプラグインで試せるのが一般" D @babel/plugin-proposal-record-and-tuple (Stage 2 D @babel/plugin-proposal-throw-expressions (Stage 2)
@babel/plugin-proposal-throw-expressions
Babelプラグインじゃ足りなかった;; Babelはあくまでコードのトランスパイルだけやってくれる(当たり前) 今回は まで含めた開発体験を手触りしたい 補完や型検査
TypeScriptで試したい TypeScriptもまだブラウザで動かない新機能をサポートして ダウンレベルコンパイルしてくれる Explicit Resource Managementとか
TypeScriptにはまだ入らない;; TypeScriptはStage 3以降の提案のみを実装するポリシー Call-this operatorはまだStage 1 https://github.com/microsoft/TypeScript/blob/a709f989/src/lib/README.md
Stage 3に進めてもらい・・・たい・・・ https://github.com/tc39/proposal-call-this プロポーザルの最終コミットが1年前、tc39/agendas でも音沙汰なし
J.S. Choiさんが忙しそう Call-this operatorとかPipeline operatorのチャンピオン 本業は内科医なのにtc39とかUnicode Consortiumとかやってる謎の人 https://github.com/js-choi
標準化は待たずに 自由研究するしかない!
TypeScriptコンパイラを雰囲気で理解する https://github.com/microsoft/TypeScript-Compiler-Notes/tree/314256/intro 公式ガイドっぽいのがあったので斜め読み microsoft/Typescript-Compiler-Note
TypeScriptコンパイラを雰囲気で理解する https://github.com/microsoft/TypeScript-Compiler-Notes/tree/314256/intro 公式ガイドっぽいのがあったので斜め読み microsoft/Typescript-Compiler-Note
トークナイザの実装 入力したコードを意味のある単位で区切った配列にする 今回は新しいトークン `~>` が登場するので対応が必要 NEW!
トークナイザの実装 作戦:似たようなトークンを見つけて追いかける ./src/compiler/types.ts
トークナイザの実装 雰囲気でトークンを定義する ./src/compiler/types.ts ./src/compiler/scanner.ts
トークナイザの実装 すでにチルダをconsumeしてるところがあったので雰囲気で付け加える ./src/compiler/scanner.ts
トークナイザの実装 それっぽくトークナイズできた!
TypeScriptコンパイラを雰囲気で理解する https://github.com/microsoft/TypeScript-Compiler-Notes/tree/314256/intro 公式ガイドっぽいのがあったので斜め読み microsoft/Typescript-Compiler-Note
パーサの実装 トークン列を木構造(AST)に変換する
ASTを考える パーサーが吐くAST構造を考えるために、既存の似ている構文を観察する globalThis.window.closeまではPropertyAccessExpressionで それを呼び出すとCallExpressionで包まれる
ASTを考える Call-this expressionも同じ構造でいけるか? → `~>` があるなら () で呼び出さないと構文エラーなのでちょっと違う。
ASTを考える レシーバから呼び出し部分まで1つのノードに入れて、 PropertyAccessExpressionとCallExpressionの合いの子みたいにする receiver expression typeArguments arguments
パーサの実装 parser.ts から実装箇所を探したいが、1万行あるのでエスパーが必須 → 仮説: `expr.name` のピリオド解析時に PropertyAccessExpression を 作っているところに相乗りできないか?
パーサの実装 それっぽい関数があった。`expr.name` の `.name` の部分を解析していそう ここから親にたどってみる
パーサの実装 `expr.name?.foo.bar` みたいなチェーンを再帰的に解析している関数があった ここに相乗りできそう!
パーサの実装 `~>` があったら CallThisExpressionとして解析するようにして完了
TypeScriptコンパイラを雰囲気で理解する https://github.com/microsoft/TypeScript-Compiler-Notes/tree/314256/intro 公式ガイドっぽいのがあったので斜め読み microsoft/Typescript-Compiler-Note
エミッタの実装 ASTをJavaScriptとして出力する
エミッタの実装 CallThisExpressionノードの子ノードを順番に出力していくだけ
嬉しいですね 入力したTypeScriptを解釈してJavaScriptに出力するところまで一通り動いた!
嬉しくない Call-this parameterを解釈できるJavaScriptランタイムはたぶんない(それはそう)
トランスフォーマの実装 ./src/transformers 配下に target ごとの実装があり、 visitor pattern で変換している 今回は esnext.ts
に足していく
トランスフォーマの実装 `receiver.fn(arg)` を `fn.call(receiver, arg)` に変換。 既に色々なfactoryがあるので組み立てるだけ
嬉しいですね 一般的なランタイムで動くJavaScriptを出せた!
嬉しくない せっかくTypeScriptなのにぶっ壊せちゃう
型チェッカの実装 5万行のクソデカ型チェッカ checker.ts をどうにかする This parameterとレシーバの型の一致をチェックする以外は 普通の関数呼び出しと同じなのでパクって実装する 変更でかいので気になる人はコミット見てください(雑) https://github.com/microsoft/TypeScript/pull/58294/commits/ ce12997edd2302325e1463ec1554ae006d8ec3b3
嬉しいですね レシーバの型エラーが出るようになった
補完も効かせたい VSCodeのTypeScript ExtensionからTS Serverに補完依頼がくる VSCode TS Server `>` で補完だしたいのだが こちらのリストでございます!
補完も効かせたい まずExtension側で `>` でも補完を呼び出すようにする TypeScript Extensionは特別にVSCodeに組み込まれているので microsoft/vscode に手を入れる ./ extensions/typescript-language-features/src/languageFeatures/completions.ts
NEW!
補完も効かせたい TypeScript (TS Server) 側ではまず `>` が Call-this なのか確かめる じゃないと普通の比較演算とかでも補完がでて困っちゃう
補完も効かせたい 補完リストは以下のロジッR まずグローバルな関数呼び出しと同様のをリストアッ( その中からレシーバとThis Parameterが一致する関数に絞る
嬉しいですね 補完が効きます
DEMO
まとめ 5 Call-this operator が来るととても嬉しいで8 5 TypeScriptに変更を加えると新規機能が実装できて楽しいです
ありがとうございました