Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Fix JSX fragment children type checking in react-jsx mode#62743

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Draft
Copilot wants to merge4 commits intomain
base:main
Choose a base branch
Loading
fromcopilot/fix-jsx-fragment-typing

Conversation

Copy link
Contributor

CopilotAI commentedNov 10, 2025
edited
Loading

Fixes#62358

JSX fragments (<>...</>) inreact-jsx/react-jsxdev modes were not type-checking children, while explicit<Fragment> worked correctly:

//@jsx: react-jsximport{Fragment}from"@/jsx-runtime";typeJsxElement=string|((arg:{foo:"bar"})=>void);interfaceFragmentProps{children?:JsxElement;}exportconstFragment:(props:FragmentProps)=>any;<Fragment>{({ foo})=>"ok"}</Fragment>;// ✓ foo: "bar"<>{({ foo})=>"not ok"}</>;// ✗ foo: any (before fix)

Changes

Extended fragment factory resolution to modern JSX modes

  • getJSXFragmentType: AddedJsxEmit.ReactJSX andJsxEmit.ReactJSXDev toshouldResolveFactoryReference check
  • Previously onlyJsxEmit.React was checked, causing fragments to returnanyType in modern modes

Added contextual typing for fragment children

  • createJsxAttributesTypeFromAttributesProperty: Extract Fragment props type from factory signature and derive children contextual type
  • checkJsxChildren: Accept optional contextual type parameter, apply to fragment child expressions viacheckExpressionForMutableLocationWithContextualType
  • Regular JSX elements unchanged - only fragments compute contextual type this way

Fixed error message for modern JSX modes

  • getJSXFragmentType: When usingreact-jsx/react-jsxdev modes, error messages now correctly reference "Fragment" instead of "React"
  • This ensures accurate error messages when using custom JSX import sources (e.g.,@jsxImportSource preact)

Test Coverage

AddedjsxFragmentChildrenCheck.tsx validating both syntaxes produce identical type checking.

Updated baselines for existing tests now correctly report error 2879 when Fragment factory is missing in react-jsx modes (previously unreported due toanyType early return), with accurate error messages showing "Fragment" as the expected factory name.

Original prompt

This section details on the original issue you should resolve

<issue_title>JSX Fragments are in-properly typed with<></> syntax, when usingreact-jsx JSX option</issue_title>
<issue_description>### 🔎 Search Terms

JSX, Fragment, children type

🕗 Version & Regression Information

Bug exists since TypeScript introduces"jsx": "react-jsx" from version 4.1.2 untilnext version (6.0.0-dev.20250830).

⏯ Playground Link

https://stackblitz.com/edit/stackblitz-starters-sffhmvvz?file=index.tsx

💻 Code

import{Fragment}from"@/jsx-runtime";<Fragment>{"ok"}{({ foo})=>"also ok"}</Fragment>;<>{"ok"}{({ foo})=>"not ok"}{/* ^ Binding element 'foo' implicitly has an 'any' type. */}</>;

With following@/jsx-runtime definition:

exportconstjsx=(...args:unknown[])=>{};typeJsxElement=|JsxElementArray|undefined|string|((arg:{foo:"bar "})=>void);interfaceJsxElementArrayextendsArray<JsxElement>{}interfaceFragmentProps{children?:JsxElement;}exportconstFragment=(props:FragmentProps)=>{};

and tsconfig:

{"compilerOptions": {"strict":true,"jsx":"react-jsx","jsxImportSource":"@",// [...]  }}

🙁 Actual behavior

The first JSX expression using<Fragment> pass the type checking while the second JSX using<> syntax reports error due to it's children was typed toany:

index.tsx:10:7 - error TS7031: Binding element 'foo' implicitly has an 'any' type.10   {({ foo }) => "not ok"}         ~~~Found 1 error in index.tsx:10

🙂 Expected behavior

These two JSX expressions should both pass the type checking.

Additional information about the issue

This issue was first mentioned at#50429 and fixed in#59933, but the fix only take effects on"jsx": "react" not"jsx": "react-jsx", while the latter is a more encouraged approach in a modern project.</issue_description>

<agent_instructions>Read the crosslinked issues and PRs, construct a test case that shows the issue and commit it, then work to fix the bug.</agent_instructions>

Comments on the Issue (you are@copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn moreCopilot coding agent tips in the docs.

@typescript-bottypescript-bot added the For Milestone BugPRs that fix a bug with a specific milestone labelNov 10, 2025
CopilotAIand others added2 commitsNovember 10, 2025 16:12
…x modeCo-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com>
… regular JSX elementsCo-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com>
CopilotAI changed the title[WIP] Fix improper typing for JSX fragments with react-jsxFix JSX fragment children type checking in react-jsx modeNov 10, 2025
Copilot finished work on behalf ofjakebaileyNovember 10, 2025 16:37
… modesCo-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com>
Copilot finished work on behalf ofjakebaileyNovember 10, 2025 16:52
@jakebailey
Copy link
Member

@typescript-bot test it

typescript-bot reacted with thumbs up emoji

@typescript-bot
Copy link
Collaborator

typescript-bot commentedNov 11, 2025
edited
Loading

Starting jobs; this comment will be updated as builds start and complete.

CommandStatusResults
test top400✅ Started✅ Results
user test this✅ Started✅ Results
run dt✅ Started✅ Results
perf test this faster✅ Started👀 Results

@typescript-bot
Copy link
Collaborator

Hey@jakebailey, the results of running the DT tests are ready.

Everything looks the same!

You can check the log here.

@typescript-bot
Copy link
Collaborator

@jakebailey Here are the results of running the user tests with tsc comparingmain andrefs/pull/62743/merge:

There were infrastructure failures potentially unrelated to your change:

  • 1 instance of "Git clone failed"

Otherwise...

Everything looks good!

@typescript-bot
Copy link
Collaborator

@jakebailey
The results of the perf run you requested are in!

Here they are:

tsc

Comparison Report - baseline..pr
MetricbaselineprDeltaBestWorstp-value
Compiler-Unions - node (v18.15.0, x64)
Errors11~~~p=1.000 n=6
Symbols62,37062,370~~~p=1.000 n=6
Types50,38650,386~~~p=1.000 n=6
Memory used195,044k (± 0.93%)195,639k (± 0.82%)~192,379k196,454kp=0.471 n=6
Parse Time1.60s (± 1.23%)1.60s (± 0.83%)~1.58s1.62sp=0.720 n=6
Bind Time0.87s (± 1.18%)0.88s (± 1.88%)~0.86s0.90sp=1.000 n=6
Check Time11.98s (± 0.51%)11.98s (± 0.59%)~11.86s12.05sp=0.872 n=6
Emit Time3.43s (± 4.16%)3.43s (± 3.30%)~3.29s3.59sp=0.936 n=6
Total Time17.89s (± 0.90%)17.88s (± 0.94%)~17.67s18.09sp=0.936 n=6
angular-1 - node (v18.15.0, x64)
Errors22~~~p=1.000 n=6
Symbols956,047956,047~~~p=1.000 n=6
Types415,881415,881~~~p=1.000 n=6
Memory used1,255,242k (± 0.01%)1,255,199k (± 0.01%)~1,255,115k1,255,287kp=0.575 n=6
Parse Time7.92s (± 0.96%)8.05s (± 0.98%)+0.13s (+ 1.58%)7.93s8.16sp=0.030 n=6
Bind Time2.27s (± 0.65%)2.28s (± 0.78%)~2.26s2.31sp=0.408 n=6
Check Time38.73s (± 0.37%)38.66s (± 0.34%)~38.53s38.85sp=0.224 n=6
Emit Time17.88s (± 0.41%)17.91s (± 0.34%)~17.82s17.96sp=0.574 n=6
Total Time66.81s (± 0.24%)66.90s (± 0.24%)~66.71s67.18sp=0.521 n=6
mui-docs - node (v18.15.0, x64)
Errors11~~~p=1.000 n=6
Symbols553,308553,308~~~p=1.000 n=6
Types8989~~~p=1.000 n=6
Memory used828,511k (± 0.01%)828,475k (± 0.00%)~828,443k828,528kp=0.173 n=6
Parse Time10.20s (± 0.71%)10.22s (± 0.61%)~10.16s10.33sp=0.809 n=6
Bind Time2.64s (± 0.61%)2.65s (± 1.03%)~2.61s2.67sp=0.567 n=6
Check Time0.00s0.00s~~~p=1.000 n=6
Emit Time0.34s (± 3.45%)0.33s (± 1.91%)~0.32s0.34sp=0.179 n=6
Total Time13.18s (± 0.72%)13.20s (± 0.58%)~13.13s13.34sp=0.809 n=6
self-build-src - node (v18.15.0, x64)
Errors00~~~p=1.000 n=6
Symbols1,237,2781,237,285+7 (+ 0.00%)~~p=0.001 n=6
Types259,884259,884~~~p=1.000 n=6
Memory used2,426,021k (± 6.10%)2,547,602k (±11.94%)~2,365,140k3,093,245kp=0.471 n=6
Parse Time5.15s (± 1.23%)5.16s (± 1.42%)~5.08s5.29sp=0.688 n=6
Bind Time1.77s (± 0.77%)1.78s (± 1.37%)~1.75s1.82sp=0.934 n=6
Check Time35.20s (± 0.80%)35.37s (± 0.88%)~34.95s35.90sp=0.471 n=6
Emit Time3.02s (± 0.80%)2.98s (± 1.41%)~2.93s3.05sp=0.128 n=6
Total Time45.15s (± 0.49%)45.29s (± 0.78%)~44.88s45.92sp=0.575 n=6
self-build-src-public-api - node (v18.15.0, x64)
Errors00~~~p=1.000 n=6
Symbols1,237,2781,237,285+7 (+ 0.00%)~~p=0.001 n=6
Types259,884259,884~~~p=1.000 n=6
Memory used3,159,630k (± 0.02%)3,039,066k (± 9.72%)~2,435,432k3,160,770kp=1.000 n=6
Parse Time6.84s (± 1.09%)6.74s (± 1.63%)~6.57s6.87sp=0.093 n=6
Bind Time2.16s (± 1.34%)2.15s (± 0.95%)~2.12s2.18sp=1.000 n=6
Check Time42.93s (± 0.27%)42.72s (± 0.45%)~42.34s42.85sp=0.066 n=6
Emit Time3.49s (± 3.17%)3.51s (± 2.04%)~3.44s3.59sp=0.936 n=6
Total Time55.42s (± 0.48%)55.13s (± 0.60%)~54.53s55.42sp=0.128 n=6
self-compiler - node (v18.15.0, x64)
Errors00~~~p=1.000 n=6
Symbols262,523262,530+7 (+ 0.00%)~~p=0.001 n=6
Types104,049104,049~~~p=1.000 n=6
Memory used440,751k (± 0.01%)440,749k (± 0.01%)~440,686k440,823kp=0.810 n=6
Parse Time3.52s (± 0.98%)3.52s (± 0.76%)~3.48s3.56sp=0.936 n=6
Bind Time1.33s (± 0.74%)1.32s (± 0.80%)~1.30s1.33sp=0.054 n=6
Check Time19.11s (± 0.37%)19.11s (± 0.42%)~19.02s19.26sp=0.809 n=6
Emit Time1.53s (± 1.23%)1.53s (± 0.76%)~1.51s1.54sp=0.807 n=6
Total Time25.48s (± 0.37%)25.47s (± 0.25%)~25.44s25.60sp=0.933 n=6
ts-pre-modules - node (v18.15.0, x64)
Errors7272~~~p=1.000 n=6
Symbols225,386225,386~~~p=1.000 n=6
Types94,30494,304~~~p=1.000 n=6
Memory used370,136k (± 0.09%)370,164k (± 0.09%)~369,911k370,793kp=0.575 n=6
Parse Time2.83s (± 0.92%)2.81s (± 1.52%)~2.74s2.86sp=0.684 n=6
Bind Time1.60s (± 0.88%)1.61s (± 0.85%)~1.59s1.62sp=0.461 n=6
Check Time16.51s (± 0.18%)16.45s (± 0.18%)-0.06s (- 0.36%)16.41s16.49sp=0.016 n=6
Emit Time0.00s0.00s (±244.70%)~0.00s0.01sp=0.405 n=6
Total Time20.94s (± 0.17%)20.88s (± 0.28%)~20.79s20.95sp=0.065 n=6
vscode - node (v18.15.0, x64)
Errors55~~~p=1.000 n=6
Symbols4,023,5754,023,575~~~p=1.000 n=6
Types1,263,8321,263,832~~~p=1.000 n=6
Memory used3,806,262k (± 0.00%)3,806,473k (± 0.01%)~3,806,123k3,806,839kp=0.230 n=6
Parse Time15.45s (± 0.53%)15.48s (± 0.79%)~15.28s15.59sp=0.630 n=6
Bind Time5.07s (± 1.99%)5.04s (± 0.60%)~5.01s5.09sp=0.808 n=6
Check Time104.26s (± 3.63%)107.51s (± 4.09%)~102.87s112.63sp=0.065 n=6
Emit Time40.20s (±14.34%)39.96s (±27.07%)~31.60s61.07sp=0.298 n=6
Total Time164.98s (± 2.45%)168.00s (± 5.66%)~161.47s186.87sp=0.689 n=6
webpack - node (v18.15.0, x64)
Errors4040~~~p=1.000 n=6
Symbols379,225379,225~~~p=1.000 n=6
Types166,383166,383~~~p=1.000 n=6
Memory used538,103k (± 0.01%)538,097k (± 0.01%)~537,989k538,175kp=0.810 n=6
Parse Time4.60s (± 0.36%)4.60s (± 0.76%)~4.57s4.66sp=1.000 n=6
Bind Time1.96s (± 1.54%)1.96s (± 1.19%)~1.92s1.99sp=0.371 n=6
Check Time22.85s (± 0.43%)22.83s (± 0.48%)~22.71s23.03sp=0.575 n=6
Emit Time0.00s0.00s~~~p=1.000 n=6
Total Time29.41s (± 0.38%)29.39s (± 0.35%)~29.26s29.57sp=0.575 n=6
xstate-main - node (v18.15.0, x64)
Errors3030~~~p=1.000 n=6
Symbols690,485690,641+156 (+ 0.02%)~~p=0.001 n=6
Types208,757208,871+114 (+ 0.05%)~~p=0.001 n=6
Memory used586,488k (± 0.03%)586,497k (± 0.02%)~586,420k586,754kp=0.689 n=6
Parse Time5.20s (± 0.52%)5.19s (± 0.71%)~5.15s5.24sp=0.469 n=6
Bind Time1.67s (± 1.54%)1.68s (± 1.06%)~1.66s1.70sp=0.682 n=6
Check Time25.83s (± 2.00%)26.14s (± 2.02%)~25.18s26.70sp=0.298 n=6
Emit Time0.01s (±109.43%)0.01s (±77.38%)~0.00s0.01sp=0.640 n=6
Total Time32.70s (± 1.63%)33.02s (± 1.64%)~32.06s33.62sp=0.336 n=6
System info unknown
Hosts
  • node (v18.15.0, x64)
Scenarios
  • Compiler-Unions - node (v18.15.0, x64)
  • angular-1 - node (v18.15.0, x64)
  • mui-docs - node (v18.15.0, x64)
  • self-build-src - node (v18.15.0, x64)
  • self-build-src-public-api - node (v18.15.0, x64)
  • self-compiler - node (v18.15.0, x64)
  • ts-pre-modules - node (v18.15.0, x64)
  • vscode - node (v18.15.0, x64)
  • webpack - node (v18.15.0, x64)
  • xstate-main - node (v18.15.0, x64)
BenchmarkNameIterations
Currentpr6
Baselinebaseline6

Developer Information:

Download Benchmarks

@typescript-bot
Copy link
Collaborator

@jakebailey Here are the results of running the top 400 repos with tsc comparingmain andrefs/pull/62743/merge:

Everything looks good!

@jakebailey
Copy link
Member

@typescript-bot pack this

typescript-bot reacted with thumbs up emoji

@typescript-bot
Copy link
Collaborator

typescript-bot commentedNov 11, 2025
edited
Loading

Starting jobs; this comment will be updated as builds start and complete.

CommandStatusResults
pack this✅ Started

@jakebailey
Copy link
Member

@typescript-bot pack this

typescript-bot reacted with thumbs up emoji

@typescript-bot
Copy link
Collaborator

typescript-bot commentedNov 11, 2025
edited
Loading

Starting jobs; this comment will be updated as builds start and complete.

CommandStatusResults
pack this✅ Started✅ Results

@typescript-bot
Copy link
Collaborator

Hey@jakebailey, I've packed this intoan installable tgz. You can install it for testing by referencing it in yourpackage.json like so:

{    "devDependencies": {        "typescript": "https://typescript.visualstudio.com/cf7ac146-d525-443c-b23c-0d58337efebc/_apis/build/builds/166506/artifacts?artifactName=tgz&fileId=6A682EAE4D1D38D9F14653D0C3D34184B74CAB8900DC1B4D91724814333BD3A102&fileName=/typescript-6.0.0-insiders.20251111.tgz"    }}

and then runningnpm install.

@ArnaudBarre
Copy link

ArnaudBarre commentedNov 11, 2025
edited
Loading

I just tested the build and I now get an error if an object is passed as a child of a shorthand fragment when usingreact-jsx 🎉

Running on 560 tsx files, it caught the same two cases than my custom linter rule (opaque type which is a number at runtime)

@jakebailey
Copy link
Member

I asked@weswigham and he said this PR is wrong, unfortunately.

ArnaudBarre and guyutongxue reacted with confused emoji

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@jakebaileyjakebaileyAwaiting requested review from jakebailey

At least 1 approving review is required to merge this pull request.

Labels

For Milestone BugPRs that fix a bug with a specific milestone

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

JSX Fragments are in-properly typed with<></> syntax, when usingreact-jsx JSX option

4 participants

@jakebailey@typescript-bot@ArnaudBarre

[8]ページ先頭

©2009-2025 Movatter.jp