Share
Embed
Transcript
14 slides
-
自己紹介 Kanaru @kanaru0928 • 普段は学生 • インフラとかバックエンドとか • 趣味 7
割、業務 3 割 興味 クラウド / アーキテクチャ 言語 Go / TypeScript / Python 2 -
背景 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 -
予想 そもそも要素名には何を入れられるか • 要素名 <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 -
パーサを見る 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