Typescript 在 nextjs 中显示 .mdx 扩展名文件错误

Wil*_*ker 6 typescript next.js

它可以很好地将组件渲染到网站,但打字稿显示导入mdx文件错误。

打字稿错误消息:找不到模块“@/articles/good.mdx”或其相应的类型声明。

我在堆栈溢出中发现了大量评论。但仍然没有解决这个问题。尝试安装@mdx-js/mdx,同样不起作用。

import React from "react";

import Layout from "@/components/Layout/index";
import Good from "@/articles/good.mdx"; // this line show typescript error

const index = () => {
  return (
    <Layout>
      <Good />
    </Layout>
  );
};

export default index;

Run Code Online (Sandbox Code Playgroud)

Package.json(删除了一些无关的)

{
  "dependencies": {
    "@next/mdx": "^10.2.0",
    "@types/react-transition-group": "^4.4.1",
    "next": "10.1.3",
    "next-seo": "^4.24.0",
    "react": "17.0.2",
    "react-dom": "17.0.2",
    "react-query": "^3.13.11",
    "react-transition-group": "^4.4.1"
  },
  "devDependencies": {
    "@mdx-js/loader": "^1.6.22",
    "@types/node": "^15.0.1",
    "@types/react": "^17.0.4",
    "@types/webpack-env": "^1.16.0",
    "autoprefixer": "^10.2.5",
    "typescript": "^4.2.4"
  }
}

Run Code Online (Sandbox Code Playgroud)

tsconfig.json(删除了一些无关的)

{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": false,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "types": [
      "node",
      "webpack-env"
     ]
  },
  "include": [
    "next-env.d.ts",
    "**/*.ts",
    "**/*.tsx",
    "**/*.mdx",
  ],
  "exclude": [
    "node_modules"
  ]
}

Run Code Online (Sandbox Code Playgroud)

小智 14

mdxjs 现在支持类型

npm install @types/mdx --save-dev
Run Code Online (Sandbox Code Playgroud)


eno*_*och 13

要解决此问题,请创建一个名为的文件mdx.d.ts,并将其放置在types项目的根目录或根目录中的文件夹中,然后粘贴以下代码:

declare module '*.mdx' {
  let MDXComponent: (props: any) => JSX.Element;
  export default MDXComponent;
}
Run Code Online (Sandbox Code Playgroud)

这定义了文件的全局类型,并告诉 typescript 从文件返回的.mdx默认导入,这使得它可以安全地在文件中用作..mdx(props: any) => JSX.Element.tsx<YourMdxComponent />


小智 7

更方便的方法是安装类型yarn add @types/mdx。然后只需将这些类型包含在您的tsconfig.ts

{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": false,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "types": [
      "node",
      "webpack-env", 
      "mdx"
     ]
  },
  "include": [
    "next-env.d.ts",
    "**/*.ts",
    "**/*.tsx",
    "**/*.mdx",
  ],
  "exclude": [
    "node_modules"
  ]
}
Run Code Online (Sandbox Code Playgroud)

如果您想从 mdx 文件重新导出自定义组件,您仍然会遇到类型错误,例如

import YourMdxContent, { SomeComponent } from './YourMdxFile.mdx'

你会得到一个错误:

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

如果发生这种情况,您将需要重新声明 mdx 模块:

declare module '*.mdx' {
  export function SomeComponent(): JSX.Element;
}
Run Code Online (Sandbox Code Playgroud)

无需重新声明 MDXContent,因为它已经继承自types.