React-Markdown中Components方法Props类型及CodeProps导入问题
问题原因
这是react-markdown版本更新导致的问题,和Next.js无关。v8及以上版本的react-markdown重构了内部模块结构,不再对外暴露react-markdown/lib/ast-to-react路径,旧的CodeProps导入方式自然失效。
解决方法
可以通过两种方式修复TypeScript类型报错:
方法一:使用内置组件类型推导
直接从react-markdown导出的Components类型中获取代码块的props类型:
'use client'; import ReactMarkdown, { Components } from 'react-markdown'; import remarkGfm from 'remark-gfm'; import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; import { oneDark } from 'react-syntax-highlighter/dist/cjs/styles/prism'; type CodeComponentProps = NonNullable<Components['code']> extends (props: infer P) => unknown ? P : never; const Markdown = ({ content }: { content: string }) => { return ( <ReactMarkdown remarkPlugins={[remarkGfm]} components={{ code({ node, inline, className, children, ...props }: CodeComponentProps) { const match = /language-(\w+)/.exec(className || ''); return !inline && match ? ( <SyntaxHighlighter style={oneDark} PreTag='div' language={match[1]} {...props}> {String(children).replace(/\n$/, '')} </SyntaxHighlighter> ) : ( <code className={className ?? ''} {...props}> {children} </code> ); }, }}> {content} </ReactMarkdown> ); }; export default Markdown;
方法二:手动定义Props类型
如果不想依赖内置类型推导,也可以直接手动定义符合结构的类型:
'use client'; import ReactMarkdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; import { oneDark } from 'react-syntax-highlighter/dist/cjs/styles/prism'; import type { Code } from 'mdast'; type CodeComponentProps = { node: Code; inline: boolean; className?: string; children: React.ReactNode; } & React.HTMLAttributes<HTMLElement>; const Markdown = ({ content }: { content: string }) => { return ( <ReactMarkdown remarkPlugins={[remarkGfm]} components={{ code({ node, inline, className, children, ...props }: CodeComponentProps) { const match = /language-(\w+)/.exec(className || ''); return !inline && match ? ( <SyntaxHighlighter style={oneDark} PreTag='div' language={match[1]} {...props}> {String(children).replace(/\n$/, '')} </SyntaxHighlighter> ) : ( <code className={className ?? ''} {...props}> {children} </code> ); }, }}> {content} </ReactMarkdown> ); }; export default Markdown;
额外说明
- 若使用
any无效,大概率是因为TS配置中noImplicitAny设为true,此时必须提供明确类型。 - 确保你的
react-markdown版本是v8+,可以通过package.json确认版本号。
内容的提问来源于stack exchange,提问作者mcrn
相关产品推荐
相关产品推荐

