Microsoft/TypeScript

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

Open

#62358 opened on Aug 30, 2025

View on GitHub
 (0 comments) (4 reactions) (1 assignee)TypeScript (48,455 stars) (6,726 forks)batch import
BugDomain: JSX/TSXFix AvailableHelp Wanted

Description

🔎 Search Terms

JSX, Fragment, children type

🕗 Version & Regression Information

Bug exists since TypeScript introduces "jsx": "react-jsx" from version 4.1.2 until next 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:

export const jsx = (...args: unknown[]) => {};

type JsxElement =
  | JsxElementArray
  | undefined
  | string
  | ((arg: { foo: "bar " }) => void);
interface JsxElementArray extends Array<JsxElement> {}

interface FragmentProps {
  children?: JsxElement;
}

export const Fragment = (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 to any:

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.

Contributor guide