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
TSX の <Hoge<Fuga>> という構文に驚いた話 / tsx-type-argume...
Search
Kanaru
July 27, 2026
Programming
280
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
TSX の <Hoge<Fuga>> という構文に驚いた話 / tsx-type-argument-syntax
Kanaru
July 27, 2026
More Decks by Kanaru
See All by Kanaru
自宅鯖のための IaC / クラウド活用
kanaru0928
0
45
Other Decks in Programming
See All in Programming
The Rails Doctrine Decade
koic
2
590
Long Living Tokens, Die, Die, Die! (or: The One Ring is Banned in Modern)
sylph01
0
310
Unity6 URPによる海底をテーマにしたVJシステムの解説 | Unity Shader 完全に理解した 勉強会
gam0022
0
370
ChromeでローカルLLM
ryu1013
0
140
設計次第でAIコードの読む量は減らせる / designing-for-code-reading
minodriven
35
17k
[Dev Group Paris Octobre 26] Agentforce, SIforce, Claudeforce, Slackbot… on s'y retrouve ?
nabondance
0
110
Vue Fes Japan の “作る側”に関わってみて
naokihaba
0
160
コードで差別化できない時代の ソフトウェアエンジニアリング / Software Engineering in an Era Where Code Doesn’t Differentiate
kishida
2
180
npm との違いを手がかりにGo の依存管理を理解したい
optim
0
540
Starting & Sustaining Code-Based E2E Testing for Non-Coding QA Teams( #jasstniigata )
teyamagu
PRO
1
1k
Workers Cache を知る
syumai
0
370
最近”作らせてる” ローカルAIアプリの話
akit37
0
470
Featured
See All Featured
Building Flexible Design Systems
yeseniaperezcruz
330
41k
Optimizing for Happiness
mojombo
378
71k
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
570
Docker and Python
trallard
47
4.2k
Chasing Engaging Ingredients in Design
codingconduct
0
360
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
2
2.9k
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
590
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
2
2.2k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
270
The browser strikes back
jonoalderson
0
1.8k
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
750
Writing Fast Ruby
sferik
630
63k
Transcript
TSX の <Hoge<Fuga>> という 構文に驚いた話 Kanaru 雑LT_study 2026-07-27
自己紹介 Kanaru @kanaru0928 • 普段は学生 • インフラとかバックエンドとか • 趣味 7
割、業務 3 割 興味 クラウド / アーキテクチャ 言語 Go / TypeScript / Python 2
背景 3
背景 AI にフロントを書かせてたら出てきた • React + TypeScript + Cloudscape(UI ライブラリ)
home.tsx !? <Cards<AnsweredEvent> header={<Header variant="h2">Events</Header>} items={answeredEvents} trackBy={(event) => event.eventId} ... /> 4
答え合わせ TypeScript のリリースノート • 型引数を表している • TS 2.9 でこの構文が追加 引用
https://www.typescriptlang.org/docs/handbook/release-notes/ typescript-2-9.html#generic-type-arguments-in-jsx-elements 5
なぜ違和感を覚えたのか 6
予想 そもそも要素名には何を入れられるか • 要素名 <Hoge fuga={piyo} /> の Hoge の部分
• <Hoge /> 一番見る形 • <Hoge<Fuga> /> さっき見た(Cloudscape など) • <Hoge.Fuga /> たまに見る(RadixUI など) 7
予想 そもそも要素名には何を入れられるか • 式ならなんでも入りそう? • <Hoge[0] /> ワンチャンいける? • <Hoge()
/> うーん怪しい • <Hoge as Fuga /> これはダメそう • 境界が謎 8
JSX の仕様書 JSX では要素名に約物(かっこなど)が入ってはいけない • 参考 https://react.github.io/jsx/#sec-jsx-elements JSX Specification OpeningElement
::= “<” ElementName [Attributes] “>” ElementName ::= Identifier | NamespacedName | MemberExpression Identifier ::= 文字列 (“<“ や “>” などの約物は除く) NamespcedName ::= Identifier “:” Identifier MemberExpression ::= Identifier “.” Identifier | MemberExpression “.” Identifier 9
TypeScript に仕様書は存在しない Microsoft「† 実装が仕様 †」 10
パーサを見る JSX は <要素名 属性 /> だけど… parser.go func (p
*Parser) parseJsxOpeningOrSelfClosingElementOrOpeningFragment (inExpressionContext bool) *ast.Expression { ... tagName := p.parseJsxElementName() var typeArguments *ast.NodeList if p.contextFlags&ast.NodeFlagsJavaScriptFile == 0 { typeArguments = p.parseTypeArguments() } attributes := p.parseJsxAttributes() ... return p.finishNode(result, pos) } 引用 https://github.com/microsoft/typescript-go/blob/typescript/v7.0.2/internal/parser/parser.go#L4933-L4966 11
パーサを見る 特別に入れられた構文 parser.go func (p *Parser) parseJsxOpeningOrSelfClosingElementOrOpeningFragment (inExpressionContext bool) *ast.Expression
{ ... tagName := p.parseJsxElementName() var typeArguments *ast.NodeList 謎の構文規則が if p.contextFlags&ast.NodeFlagsJavaScriptFile == 0 { typeArguments = p.parseTypeArguments() 足されている!! } attributes := p.parseJsxAttributes() ... return p.finishNode(result, pos) } 引用 https://github.com/microsoft/typescript-go/blob/typescript/v7.0.2/internal/parser/parser.go#L4933-L4966 12
パーサを見る 分かったこと • 要素名は「項」や「式」などの単位ではなく専用の構文が存在する • 識別子(Hoge) • メンバー式(Hoge.Fuga.Piyo) • 名前空間付き識別子(Hoge:Fuga)
• (TS 限定)型引数が付与可能(Hoge<Fuga>) • 型引数が特別扱いなので違和感があった 13
結論 積極的に使うことはなさそう • ほとんどのケースで型推論が効く • 可読性が悪い • そんな複雑なコンポーネントを作る機会がない explicit.tsx <Cards<AnsweredEvent>
items={answeredEvents} ... /> 型推論により 省略可能 implicit.tsx <Cards items={answeredEvents} ... /> 14