使用子路径导出时无法使 Typescript 定义正常工作

oli*_*ren 6 typescript package.json

在我的项目(最新提交)中,我的 package.json 中有两个导出:

  "exports": {
    ".": "./dist/index.js",
    "./react-lazy": "./dist/react-lazy.js"
  },
Run Code Online (Sandbox Code Playgroud)

在 JS 项目中使用它效果很好,但 TS 项目抱怨在我将一个模块拆分为子路径导出后找不到类型。

然后我尝试了我在另一个答案中看到的“扩展”导出版本:

  "exports": {
    ".": {
      "import": "./dist/index.js",
      "types": "./types/index.d.ts"
    },
    "./react-lazy": {
      "import": "./dist/react-lazy.js",
      "types": "./types/react-lazy.d.ts"
    }
  },
Run Code Online (Sandbox Code Playgroud)

不去。

然后我尝试了另一种方法typesVersion

  "typesVersions": {
    "*": {
      ".": "./types/index.d.ts",
      "./react-lazy": "./types/react-lazy.d.ts"
    }
  },
Run Code Online (Sandbox Code Playgroud)

还有,不去。是什么赋予了?现在我对这里的问题有点困惑。

尝试此操作时,我从测试项目中npm link启动了该项目并运行。npm link @fatso83/retry-dynamic-importtsc --lib es2015,dom --noEmit main.ts

我基本上只是测试这些行是否通过编译器:

import { dynamicImportWithRetry } from "@fatso83/retry-dynamic-import";

import reactLazy from "@fatso83/retry-dynamic-import/react-lazy";
Run Code Online (Sandbox Code Playgroud)

目前,上述所有尝试都以

$ tsc --lib es2015,dom --noEmit main.ts
main.ts:3:40 - error TS2307: Cannot find module '@fatso83/retry-dynamic-import' or its corresponding type declarations.

3 import { dynamicImportWithRetry } from "@fatso83/retry-dynamic-import";
                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)

如果我只是导出 index.js,一切都会很好,因为这有效:

  "exports": "./dist/index.js",
  "types": "./types/index.d.ts",
Run Code Online (Sandbox Code Playgroud)

这将使第一行通过,但不会使第二行通过。

oli*_*ren 4

让一切正常工作的答案是,当且仅当您设置moduleResolutionnodeNextor时,TypeScript 支持子路径导入node16

不幸的是,无论出于何种原因,这也会迫使您在动态导入时指定文件扩展名(如import('./foo.ts').

所以上面的 TSC 命令只是稍微调整了一下:

$ npx tsc --esModuleInterop true --lib es2015,dom --noEmit --moduleResolution nodeNext main.ts
Run Code Online (Sandbox Code Playgroud)

然后一切都正常了。

不幸的是,我不确定其他消费者会认为这有多热......这意味着要么公开一个可能会传递性地引入 React 的包(如果不使用子路径导出),即使不使用它,要么强制消费者添加扩展他们的动态进口。

编辑:适用于所有环境的解决方法 虽然上面确实回答了如何以及为什么的问题,但它以使用子路径功能如何影响客户端的几点结束。事实证明,如果您使用子路径导出的唯一原因是您的模块位于./dist目录中,则可以通过对创建和发布包的方式进行一些调整,使文件在根目录下可导入,从而避免整个问题。这是我的设置(标记以避免链接失效):

这基本上将package.json,./dist/*./types/*文件复制到一个./pkg文件夹中,然后手动调整类型定义以包含特定于反应的模块。

虽然这不是我提出的问题的解决方案,但它可能是很多人真正想要的解决方案(也是我需要的解决方案)。您可以看到我的构建脚本还测试了消费者,这是一种集成测试,我尝试在各种 Typescript 设置中使用我的包以查看它没有问题,所以这确实有效:)