如何在 NPM 上创建仅限类型的包

eak*_*akl 7 npm typescript monorepo

我想创建一个仅导出类型的包(monorepo 或 NPM),以便在我的项目中我可以这样导入它们

import type { MyType } from '@acme/types'
Run Code Online (Sandbox Code Playgroud)

我已尝试以下解决方案,但它不起作用

项目结构

package.json
index.d.ts
Run Code Online (Sandbox Code Playgroud)

索引.d.ts

export type MyType = {
  name: string
}
Run Code Online (Sandbox Code Playgroud)

包.json

import type { MyType } from '@acme/types'
Run Code Online (Sandbox Code Playgroud)

当我想导入我的类型时,出现此错误

File '/Users/acme/packages/types/index.d.ts' is not a module. ts(2306)

我也尝试过重命名index.d.tsindex.ts. 也不起作用

jse*_*ksn 9

请参阅TypeScript 手册中的声明文件 > 发布以获取与此主题相关的信息,并查看DefinelyTyped 存储库以获取大量示例。

\n
\n

在一个简单的场景中,例如您的问题中详细描述的场景,提供程序包中所需的唯一部分是:

\n
    \n
  1. 类型声明文件,包括名为 的入口点声明文件index.d.ts,以及

    \n
  2. \n
  3. 满足 Node.js 模块定义的最低标准:package.json具有所需字段的清单文件:name以及version

    \n
  4. \n
\n

因此,假设您的提供程序包目录位于./provider,所需的文件将如下所示:

\n

./provider/package.json

\n
{\n  "name": "@acme/types",\n  "version": "0.1.0"\n}\n\n
Run Code Online (Sandbox Code Playgroud)\n

./provider/index.d.ts

\n
export type MyType = {\n  name: string;\n};\n\n
Run Code Online (Sandbox Code Playgroud)\n

以下注释包含在链接的 TS 手册页面中的“在 npm 包中包含声明”部分中:

\n
\n

另请注意,如果您的主声明文件已命名index.d.ts并且位于包的根目录中,则无需标记该types属性,但建议这样做。

\n
\n

因此,您可能会考虑显式定义该字段,而不是依赖自动解析行为:

\n

./provider/package.json

\n
{\n  "name": "@acme/types",\n  "version": "0.1.0",\n  "types": "./index.d.ts"\n}\n\n
Run Code Online (Sandbox Code Playgroud)\n
\n

现在,这就是 \xe2\x80\x94 问题的答案,但我还将提供一个示例消费者包,其中包含用于演示的复制步骤。

\n
\n

如果您想继续操作,可以复制并粘贴以下每个示例文件,在您的文件系统中重新创建它们。或者您可以在浏览器的 JS 控制台中运行此脚本来下载整个项目结构的 zip 存档:

\n
(() => {\n  function createBase64DataUrl(mediaType, b64Str) {\n    return `data:${mediaType};base64,${b64Str}`;\n  }\n\n  function download(url, fileName) {\n    const a = document.createElement("a");\n    a.href = url;\n    a.download = fileName;\n    a.click();\n    a.remove();\n  }\n\n  const zipArchiveData = "UEsDBAoAAAAAADQOe1YAAAAAAAAAAAAAAAAJABwAcHJvdmlkZXIvVVQJAAODPCFkjjwhZHV4CwABBPUBAAAEFAAAAFBLAwQUAAAACABObHtWF0wQhEEAAABNAAAAFQAcAHByb3ZpZGVyL3BhY2thZ2UuanNvblVUCQADs+EhZLPhIWR1eAsAAQT1AQAABBQAAACr5lJQUMpLzE1VslJQckhMzk3VL6ksSC1W0gFJlKUWFWfm54HkDPQM9QwgohAFQDE9/cy8lNQKvRS9kmIlrlouAFBLAwQUAAAACAA5DntWXPRvjCkAAAAqAAAAEwAcAHByb3ZpZGVyL2luZGV4LmQudHNVVAkAA448IWSPPCFkdXgLAAEE9QEAAAQUAAAAS60oyC8qUSipLEhV8K0MAVG2CtVcCgp5ibmpVgrFJUWZeenWXLXWXABQSwMECgAAAAAA53R7VgAAAAAAAAAAAAAAAAkAHABjb25zdW1lci9VVAkAA+HwIWTk8CFkdXgLAAEE9QEAAAQUAAAAUEsDBBQAAAAIANdye1bERSpvhQAAAL8AAAAVABwAY29uc3VtZXIvcGFja2FnZS5qc29uVVQJAAMF7SFkBe0hZHV4CwABBPUBAAAEFAAAAE2NvQrDMAwGdz+F0VwUt9AlU4c+RyHIKhjqH2zXNIS8e2WnQ9fvTqdNaQ1h8QyzBoqhvD1nOPW1cS4uhg4MntEcq+V258TBciDHRegms4DbQp6nuqYxwtO9eEacUo7N2V9TtCFQdql263FFgxcQtI/6Qf6qFH2SUndrIe3k7wdF6BdqV19QSwMEFAAAAAgAcXB7VscThVtUAAAAZAAAABEAHABjb25zdW1lci9pbmRleC50c1VUCQADhughZIfoIWR1eAsAAQT1AQAABBQAAADLzC3ILypRKKksSFWoVvCtDAExahXSivJzFZQcEpNzU/VBcsVK1lxcyfl5xSUK+UlZVjCFtkA9eYm5qVYKSmn5+UoKtVBV+Tmpejn56RpAtZrWXABQSwECHgMKAAAAAAA0DntWAAAAAAAAAAAAAAAACQAYAAAAAAAAABAA7UEAAAAAcHJvdmlkZXIvVVQFAAODPCFkdXgLAAEE9QEAAAQUAAAAUEsBAh4DFAAAAAgATmx7VhdMEIRBAAAATQAAABUAGAAAAAAAAQAAAKSBQwAAAHByb3ZpZGVyL3BhY2thZ2UuanNvblVUBQADs+EhZHV4CwABBPUBAAAEFAAAAFBLAQIeAxQAAAAIADkOe1Zc9G+MKQAAACoAAAATABgAAAAAAAEAAACkgdMAAABwcm92aWRlci9pbmRleC5kLnRzVVQFAAOOPCFkdXgLAAEE9QEAAAQUAAAAUEsBAh4DCgAAAAAA53R7VgAAAAAAAAAAAAAAAAkAGAAAAAAAAAAQAO1BSQEAAGNvbnN1bWVyL1VUBQAD4fAhZHV4CwABBPUBAAAEFAAAAFBLAQIeAxQAAAAIANdye1bERSpvhQAAAL8AAAAVABgAAAAAAAEAAACkgYwBAABjb25zdW1lci9wYWNrYWdlLmpzb25VVAUAAwXtIWR1eAsAAQT1AQAABBQAAABQSwECHgMUAAAACABxcHtWxxOFW1QAAABkAAAAEQAYAAAAAAABAAAApIFgAgAAY29uc3VtZXIvaW5kZXgudHNVVAUAA4boIWR1eAsAAQT1AQAABBQAAABQSwUGAAAAAAYABgAEAgAA/wIAAAAA";\n  const dataUrl = createBase64DataUrl("application/zip", zipArchiveData);\n  download(dataUrl, "so-75850348.zip");\n})();\n
Run Code Online (Sandbox Code Playgroud)\n
\n

鉴于消费者包目录位于./consumer,它可能会从此最小包文件开始:

\n

./consumer/package.json

\n
{\n  "name": "consumer",\n  "version": "0.1.0"\n}\n\n
Run Code Online (Sandbox Code Playgroud)\n

第一步是安装 TypeScript 和提供程序类型包作为开发依赖项:

\n
$ cd ./consumer\n$ npm install --save-dev typescript ../provider\n\nadded 2 packages, and audited 4 packages in 616ms\n\nfound 0 vulnerabilities\n
Run Code Online (Sandbox Code Playgroud)\n
\n

每个包都可以使用单独的命令安装:

\n
npm install --save-dev typescript\nnpm install --save-dev ../provider\n
Run Code Online (Sandbox Code Playgroud)\n
\n

之后,package.json将包含以下依赖项:

\n
{\n  "name": "consumer",\n  "version": "0.1.0",\n  "devDependencies": {\n    "@acme/types": "file:../provider",\n    "typescript": "^5.0.2"\n  }\n}\n\n
Run Code Online (Sandbox Code Playgroud)\n

我们希望在某些代码中使用这些类型,因此让我们创建一个基本的 TypeScript 文件,该文件将使用包中的类型:

\n

./consumer/index.ts

\n
import type { MyType } from "@acme/types";\n\nconst obj: MyType = { name: "foo" };\n\nconsole.log(obj);\n\n
Run Code Online (Sandbox Code Playgroud)\n

接下来,让我们向该文件添加一个npm 脚本package.json,该脚本将使用编译器默认值 \xe2\x80\x94 编译 TypeScript 文件,我们将命名该脚本compile

\n
{\n  "name": "consumer",\n  "version": "0.1.0",\n  "devDependencies": {\n    "@acme/types": "file:../provider",\n    "typescript": "^5.0.2"\n  },\n  "scripts": {\n    "compile": "tsc index.ts"\n  }\n}\n\n
Run Code Online (Sandbox Code Playgroud)\n
\n

在大多数情况下,您可能希望使用 TSConfig 为项目配置编译器行为

\n
\n

现在,让我们编译该文件并运行它:

\n
$ npm run compile && node index.js\n\n> consumer@0.1.0 compile\n> tsc index.ts\n\n{ name: \'foo\' }\n
Run Code Online (Sandbox Code Playgroud)\n

编译成功,没有问题,文件按预期运行。

\n
\n

请注意,我在编写此答案时正在使用此 Node LTS 版本:

\n
$ node --version\nv18.15.0\n
Run Code Online (Sandbox Code Playgroud)\n
\n