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

在TypeScript与Next.js中无法修改MDX导出类型的求助

问题

我开发了一个自定义插件,用于将MDX文件中的frontmatter转换为名为frontMatter的常量导出。例如a.mdx文件:

---
title: "Some Title"
---

# Content

在Next.js页面中直接导入时,编译阶段会被转换为:

# Content

export const frontMatter = {
    title: "Some Title"
}

因此我在TypeScript + Next.js的页面文件中这样导入:

import AComponent, { frontMatter } from "a.mdx"

frontMatter的功能完全正常,但TypeScript编译器无法识别这个自定义导出——除非在MDX文件中显式写出该导出。我尝试声明模块,也确认tsconfig已经包含了类型定义文件,当前的模块声明如下:

declare module '*.mdx' {
    import { MDXProps } from 'mdx/types'
    const MDXComponent: (props: MDXProps) => JSX.Element
    const frontMatter: { [key: string]: any }
    export { frontMatter }
    export default MDXComponent
}

但这个声明完全不起作用。不过我做了个测试:在同一个类型文件中声明如下模块时,导入是正常的:

declare module '*.myFile' {
   export const value
}

我收到的具体错误提示是:

Module '"index.mdx"' has no exported member 'frontMatter'. Did you mean to use 'import frontMatter from "index.mdx"' instead?

我推测应该是有其他内容覆盖了MDX的类型定义,无论怎么调整自定义声明都无效。我的tsconfig.json配置如下:

{
    "compilerOptions": {
        "lib": ["dom", "dom.iterable", "esnext"],
        "allowJs": true,
        "skipLibCheck": true,
        "strict": true,
        "noEmit": true,
        "esModuleInterop": true,
        "module": "esnext",
        "moduleResolution": "bundler",
        "resolveJsonModule": true,
        "isolatedModules": true,
        "jsx": "preserve",
        "incremental": true,
        "plugins": [
            {
                "name": "next"
            }
        ],
        "paths": {
            ... Some remappings here
        }
    },
    "include": [
        "next-env.d.ts",
        "**/*.ts",
        "**/*.tsx",
        "**/*.mdx",
        ".next/types/**/*.ts",
        "THE MODULE DECLARATION FILE"
    ],
    "exclude": ["node_modules"]
}
解决方案

1. 排查冲突的类型定义

Next.js或MDX官方可能自带了*.mdx的类型声明,导致你的自定义声明被覆盖:

  • 检查node_modules下的@types/mdx、next/dist/types目录,看看是否存在MDX相关的默认类型定义。
  • 将自定义类型声明文件命名为mdx.d.ts,放在项目根目录或src/types文件夹下,确保它在TypeScript的扫描路径内。

2. 修正模块声明写法

调整声明结构,确保类型导出符合TypeScript规范:

declare module '*.mdx' {
  import type { MDXProps } from 'mdx/types';
  const Component: (props: MDXProps) => JSX.Element;
  export const frontMatter: Record<string, unknown>;
  export default Component;
}

这里用type导入避免运行时冗余引用,同时用Record<string, unknown>替代{ [key: string]: any },类型更严谨。

3. 调整tsconfig配置

  • 确保include数组中的类型声明文件路径正确,比如如果放在src/types/下,就写src/types/**/*.d.ts,不要硬编码文件名。
  • 在compilerOptions中添加typeRoots,让TypeScript优先加载自定义类型:
"compilerOptions": {
  // 其他配置保持不变
  "typeRoots": ["./src/types", "./node_modules/@types"]
}

这样自定义类型会比node_modules里的类型更早被加载,避免被覆盖。

4. 清除Next.js缓存

缓存可能导致类型未更新,执行以下命令清理后重新构建:

rm -rf .next
npm run build

内容的提问来源于stack exchange,提问作者cpix

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 21:06:02