Types of property 'pre' are incompatible when using inside MDXComponents for generating RSS feed #1940
-
|
I am trying to generate RSS feed using MDX. I have a bunch of custom MDX components: import React from 'react'
import { getMDXComponent } from 'mdx-bundler/client'
import { Img } from '@/components/mdx/Img'
import { Pre } from '@/components/mdx/Pre'
import { TOC } from '@/components/mdx/TOC'
import { Sidenote } from '@/components/mdx/Sidenote'
export const MDXComponents = {
pre: Pre,
Img,
TOC,
Sidenote,
}
interface IMDXLayoutRenderer {
mdxSource?: any
}
export const MDXLayoutRenderer = ({ mdxSource, ...rest }: IMDXLayoutRenderer): JSX.Element => {
const MDXLayout = React.useMemo(() => getMDXComponent(mdxSource), [mdxSource])
return <MDXLayout components={MDXComponents as any} {...rest} />
}The import React from 'react'
import { CopyToClipboard } from '@/components/index'
interface IPre {
children: React.ReactChild
theme: string
showLineNumbers: boolean
}
export const Pre = ({ children, theme, showLineNumbers, ...props }: IPre) => {
return (
<CopyToClipboard>
<pre
className={`px-4 py-3 overflow-x-auto rounded-lg font-jetbrains ${
theme ? `${theme}-theme` : 'bg-syntaxBg'
} ${showLineNumbers ? 'line-numbers' : ''}`}
>
{children}
</pre>
</CopyToClipboard>
)
}It's usage is like this in my const mdx = (
<MDXProvider components={MDXComponents}>
<MDXLayoutRenderer mdxSource={code} />
</MDXProvider>
)I believe this is due to a mismatch in what The complete error looks like:
How do I solve this? This error is far too common whenever I use a Custom MDX Component. I'm using it with |
Beta Was this translation helpful? Give feedback.
Replies: 9 comments 20 replies
-
|
The problem is explained in the error message: You can’t just say that |
Beta Was this translation helpful? Give feedback.
-
|
only doing const mdx = (
<MDXProvider components={MDXComponents as any}>
<MDXLayoutRenderer mdxSource={code} />
</MDXProvider>
) |
Beta Was this translation helpful? Give feedback.
-
|
The issue is interface IPre {
children: React.ReactChild
theme: string
showLineNumbers: boolean
}
interface IPre {
children: React.ReactElement;
theme?: string;
showLineNumbers?: boolean;
}Example in sandbox showing that it can be typed without |
Beta Was this translation helpful? Give feedback.
-
|
I'm having the same problem. I'm using next-mdx-remote with Typescript 5.2.2. If I set strict mode in tsconfig.json following error occurs. The error disappears if I disable strict mode or set @ts-expect-error directive as following: export default function MDXContent({source}: {source: string}) {
// @ts-expect-error Server Component
return <MDXRemote source={source} components={comps} options={opts} />
} |
Beta Was this translation helpful? Give feedback.
-
|
Thanks a lot. I've verified deduped @types/react package as following: and npm packages as following: Then, how can I resolve the problem? Indeed I'm newbie in Javascript world. The |
Beta Was this translation helpful? Give feedback.
-
|
Thank you for your reply. I found the problem is caused by Next.js. It seems they ignoring tsconfig.json settings. The error persists on Visual Studio Code even if I changed the settings to $ npm run build
> monzy@0.1.0 build
> next build
▲ Next.js 14.0.1
- Environments: .env
✓ Creating an optimized production build
✓ Compiled successfully
Linting and checking validity of types ..
We detected TypeScript in your project and reconfigured your tsconfig.json file for you. Strict-mode is set to false by default.
The following mandatory changes were made to your tsconfig.json:
- jsx was set to preserve (next.js implements its own optimized jsx transform)
Linting and checking validity of types ..Failed to compile.
./app/components/MDXContent.tsx:32:37
Type error: Type '{ pre: ({ children, ...props }: IPre) => React.ReactElement<any, string | React.JSXElementConstructor<any>>; Button: ({ text }: { text: string; }) => React.JSX.Element; }' is not assignable to type 'Readonly<MDXComponents> | MergeComponents | null | undefined'.
Type '{ pre: ({ children, ...props }: IPre) => React.ReactElement<any, string | React.JSXElementConstructor<any>>; Button: ({ text }: { text: string; }) => React.JSX.Element; }' is not assignable to type 'Readonly<MDXComponents>'.
Types of property 'pre' are incompatible.
Type '({ children, ...props }: IPre) => React.ReactElement<any, string | React.JSXElementConstructor<any>>' is not assignable to type 'Component<DetailedHTMLProps<HTMLAttributes<HTMLPreElement>, HTMLPreElement>> | undefined'.
Type '({ children, ...props }: IPre) => React.ReactElement<any, string | React.JSXElementConstructor<any>>' is not assignable to type '(props: DetailedHTMLProps<HTMLAttributes<HTMLPreElement>, HTMLPreElement>) => ReactNode'.
Types of parameters '__0' and 'props' are incompatible.
Type 'DetailedHTMLProps<HTMLAttributes<HTMLPreElement>, HTMLPreElement>' is not assignable to type 'IPre'.
Types of property 'children' are incompatible.
Type 'ReactNode' is not assignable to type 'ReactElement<any, string | JSXElementConstructor<any>>'.
Type 'undefined' is not assignable to type 'ReactElement<any, string | JSXElementConstructor<any>>'.
30 | export default function MDXContent({source}: {source: string}) {
31 | // cba@ts-expect-error Server Component
> 32 | return <MDXRemote source={source} components={comps} options={opts} />
| ^
33 | }
34 | |
Beta Was this translation helpful? Give feedback.
-
|
Sorry again for my inconvenience. I realized my case should be concrete(I have to use CodeBlock component with import { MDXRemote } from '@/app/lib/next-mdx-remote/rsc'
import CodeBlock from './CodeBlock';
interface CodeBlockProps {
children: React.ReactElement;
}
const comps = { pre: CodeBlock };
export default function MDXContent({source}: {source: string}) {
// ignore@ts-expect-error Server Component
return <MDXRemote source={source} components={comps} options={opts} />
} |
Beta Was this translation helpful? Give feedback.
-
|
I've found type casting can be a workaround. import { MDXComponents } from 'mdx/types';
const comps = { pre: CodeBlock, } as MDXComponents; |
Beta Was this translation helpful? Give feedback.
The issue is
childrenof intrinsic elements isReact.ReactElementnotReact.ReactChildthemeandshowLineNumbersshould also be marked as optional because they may not be passed.Example in sandbox showing that it can be typed without
anyhttps://codesandbox.io/s/component-typing-example-dvc35?file=/src/App.tsx:73-170