You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 05:42:47