网站搜索

next.js - 在 nextjs 中使用自定义 TypeScript 类型定义 .d.ts(模块未找到:无法解析...)


我正在使用的 JS 库没有为 TypeScript 提供 @type 定义,所以我创建了自己的 .d.ts 文件。我们称它为 foo.d.ts。我的项目结构如下:

...
.next/
pages/
...
typings/
    foo.d.ts
...
tsconfig.json

我的 VS Code 对那个定义没有问题,并且我可以在我的组件中进行导入,比如:

import {Foo} from "foo";

但在运行时,我在浏览器控制台中收到此错误

未找到模块:无法解析 'foo'

我已经尝试添加

"typeRoots": ["node_modules/@types", "typings"]

到我的 tsconfig.json 但没有帮助。我也尝试过在 include 部分显式添加 foo.d.ts,就像添加 next-env.d.ts 一样。

foo.d.ts 看起来是这样的:

declare module 'foo' {
    declare interface ValidationError {
        message?: string;
    }
    declare namespace Foo {
        class Bar {
            constructor(config: any, displayErrorsCallback: (data: ValidationError[]) => void, onSubmitTriggered: () => void);
        }
    }
}

更新(添加了 tsconfig)

{
  "compilerOptions": {
    "target": "es6",
    "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",
    "typeRoots": [
      "node_modules/@types",
      "typings"
    ]
  },
  "include": [
    "next-env.d.ts",
    "**/*.ts",
    "**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}

答案#1

只需在文件名后加上 .d,所以将你的类型定义导入为 import {Foo} from "foo.d"; 每当导入 *.d.ts 时,就这样导入,无需编辑配置。

答案#2

在使用 NextJS 14 时,我今天遇到了这个问题。

最终,我不得不以这种方式指定 typeRoots (之前没有指定,一直在使用我不清楚的某些默认值):

"typeRoots": [
  "@typings",
  "node_modules",
  "node_modules/@types"
],

解释(如果我没说错的话):

  • @typings 是我自己的外部类型文件夹(只包含 d.ts 文件)
  • node_modules 可能包含 d.ts 类型,因为一些包会将它们与源代码一起发布 (这就是我缺少的内容,并且导致 next build 失败)
  • node_modules/@types 是模块发布其类型定义的地方(最佳实践,但并不总是遵循)

完整的 tsconfig.json 文件:

{
  "$schema": "https://json.schemastore.org/tsconfig",
  "display": "Next.js",
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
    "baseUrl": ".",
    "types": [
      "node",
      "jest",
      "@testing-library/jest-dom"
    ],
    "typeRoots": [
      "@typings",
      "node_modules",
      "node_modules/@types"
    ],
    "plugins": [
      {
        "name": "next"
      }
    ]
  },
  "include": [
    "next-env.d.ts",
    "**/*.ts",
    "**/*.tsx",
    "**/*.mjs",
    "jest.config.js",
    ".next/types/**/*.ts"
  ],
  "exclude": [
    "node_modules"
  ]
}

相关文章