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
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
260
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
41
Other Decks in Programming
See All in Programming
Seeing Through Serverless: Observability for AWS Lambda with ADOT and CloudWatch Application Signals
seike460
PRO
1
130
Go × SIMDで高速化するベクトル検索 ~ルーフラインモデルでSIMDが効く境界を探れ! ~
po3rin
1
160
Hello, Hiroshima Geospatial Data! — Exploring DoboX with Python
ra0kley
0
180
AWS Step Functions 大規模並列の壁を越える / jaws-sonic-2026-niigata-step-functions
kasacchiful
PRO
1
410
20260828_品質と開発生産性を両立させる、AI時代のE2Eテストの考え方
magicpod
0
170
[GoCon2026] When Goroutines Are Not Enough: Runtime Locality in High-Throughput Go
takehaya
5
890
GKE アップグレード前に知っておきたい Blue/Green と PDB の関係
stkk
0
160
FastAPI の並行処理モデルを完全に理解する
hoto17296
9
3.8k
マイコン向けの軽量Ruby「PicoRuby」で各種デバイスを制御するネイティブアプリの実現手法
bash0c7
0
180
Swift愛好会と私(ウホーイ) / Swift Fan Club and Uhooi
uhooi
0
150
MIZARU@SPAJAM2026 第二回予選
1901drama
0
110
個人開発基盤をまるごとCloudflareに引っ越して爆速で総合的体験を向上させた話
tinykitten
0
140
Featured
See All Featured
The Language of Interfaces
destraynor
162
27k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
How to build a perfect <img>
jonoalderson
1
6k
Believing is Seeing
oripsolob
1
210
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
450
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.3k
Six Lessons from altMBA
skipperchong
29
4.5k
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
500
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
Producing Creativity
orderedlist
PRO
348
41k
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
300
A Soul's Torment
seathinner
7
3.6k
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