Skip to content
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typescript Error ts(2322) for Nested MDX Components in React19 environment #2579

Closed
4 tasks done
talatkuyuk opened this issue Jan 14, 2025 · 5 comments
Closed
4 tasks done
Labels
💪 phase/solved Post is done

Comments

@talatkuyuk
Copy link
Contributor

Initial checklist

Affected package

mdx/types@latest

Steps to reproduce

Related with the type MDXComponents of @types/mdx, I am facing a typescript error ts2322 in react19 environment (no problem with react18):

import React from "react";
import { evaluate } from "@mdx-js/mdx";
import * as runtime from "react/jsx-runtime";
import type { MDXComponents } from "mdx/types";

export default async function Home() {
  const { default: MDXContent } = await evaluate("<motion.p />", runtime);

  const components: MDXComponents = {
    motion: { p: () => <p>Hello world</p> },
  };

  return MDXContent({ components });
}

The type MDXComponents raises an error for nested MDX components, under the motion key specifically in above example , saying:

Type '{ p: () => React.JSX.Element; }' is not assignable to type '(NestedMDXComponents | Component<any>) & (Component<JSX.IntrinsicElements> | undefined)'.
  Type '{ p: () => React.JSX.Element; }' is not assignable to type 'NestedMDXComponents & (new (props: JSX.IntrinsicElements) => JSX.ElementClass)'.
    Type '{ p: () => React.JSX.Element; }' is not assignable to type 'new (props: JSX.IntrinsicElements) => JSX.ElementClass'.
      Type '{ p: () => Element; }' provides no match for the signature 'new (props: JSX.IntrinsicElements): JSX.ElementClass'.ts(2322)

I suppose the typescript can not narrow NestedMDXComponents to FunctionComponent<Props> or ClassComponent<Props>. I don't know the issue may be related with JSX issue, because when I add the code suggested by @wooorm disappears the error, but couldn't figure out the reason.

import type { JSX as Jsx } from "react/jsx-runtime";

declare global {
  namespace JSX {
    type ElementClass = Jsx.ElementClass;
    type Element = Jsx.Element;
    type IntrinsicElements = Jsx.IntrinsicElements;
  }
}

I also saw a typescript comment in the documentation (using-mdx.mdx) here

// @errors: 2322 -- something with React 19 and nested components.

I created two minimal apps with Next.js to investigate the error:

  • First app is Next.js@15 (React19), having typescript error for the type MDXComponents for nested MDX components.
  • Second app is Next.js@14 (React18), having NO typescript error for nested MDX components.

Actual behavior

The typescript throws aforementioned error for the type MDXComponents for nested MDX components in React19 environment.

Expected behavior

Normally, it would work with nested MDX components without any typescript error.

Runtime

node@20

Package manager

npm@11

Operating system

macOS@latest

Build and bundle tools

Next.js

@github-actions github-actions bot added 👋 phase/new Post is being triaged automatically 🤞 phase/open Post is being triaged manually and removed 👋 phase/new Post is being triaged automatically labels Jan 14, 2025
@wooorm
Copy link
Member

wooorm commented Jan 15, 2025

@types/react indeed removed JSX. JSX is needed otherwise the types cannot work. There is no alternative to support all frameworks if frameworks do not specify their types somehow. So it is indeed recommended to type JSX like that

@talatkuyuk
Copy link
Contributor Author

Thanks @wooorm;

I added the global JSX namespace in the Next.js 15 project the location where I need to use nested MDX components. In this time, the IntrinsicElements type definition has ensured sufficiency to remove the type error.

import type { JSX as ReactJSX } from "react";
declare global {
  namespace JSX {
    type IntrinsicElements = ReactJSX.IntrinsicElements;
  }
}

As author of next-mdx-remote-client, I will not add the global JSX namespace definition into the package (for example via global.d.ts), let developers define it their project if they need to use nested MDX components. Do you agree with me ?

Thanks for the answer.

@wooorm
Copy link
Member

wooorm commented Jan 30, 2025

Do you agree with me ?

👍 yep I do — for now I think it best that end users choose!

@talatkuyuk
Copy link
Contributor Author

Thank you very much @wooorm.

This comment has been minimized.

@wooorm wooorm added the 💪 phase/solved Post is done label Jan 31, 2025
@github-actions github-actions bot removed the 🤞 phase/open Post is being triaged manually label Jan 31, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
💪 phase/solved Post is done
Development

No branches or pull requests

2 participants