如何在 TypeScript (Node.js) 包中包含全局文件类型声明

How to include a global file type declaration in a TypeScript (Node.js) package

我正在开发一个我计划在 npmjs 上公开发布的包。我们称它为“文本包”吧。

我希望在安装该软件包时默认情况下,您可以直接导入 .txt 文件并获得正确的类型(开箱即用),如下所示:

import text from './file.txt'

text 变量将是 string 类型,因为包会定义它的类型,使用类似这样的东西(在 global.d.ts 中):

declare module '*.txt' {
    export const text: string;
    export default text;
}

如果我在我的包中包含 global.d.ts,并且我从这个包中导入了一些东西,那么我将在导入 .txt 文件时自动获得正确的类型。

但问题是有时我只需要导入一个 .txt 文件而不从“文本包”导入任何东西,这就是为什么我想知道是否有某种方式,因为你安装一个安装全局类型的包,不需要为要应用的类型导入任何其他内容。

换句话说,一旦您安装了我的“txt 包”,declare module '*.txt' 就会立即应用于我的整个项目。

有没有办法做到这一点,或者安装我的包的人必须声明他们自己的全局类型(例如,declarations.d.ts)才能全局导入 .txt 文件?

我知道即使导入类型有效,它仍然需要 Webpack 或其他捆绑器才能真正工作,但这个问题只是关于类型。

要捆绑全局类型,请执行以下操作。 form typescript

  • typeRoots 指定默认类型目录。 .e.g "typeRoots": ["./src/types"].
  • 在指定目录下创建文件/src/types/global.d.ts
  • declare global {} 内的文件中声明您的类型,如果您还没有导出任何内容,请确保有 export {}

简短的回答是:

如果不导入引用类型的文件,TypeScript 不支持全局类型。

更多详情:

我发现这样做的一个例子是 Next.js - 在使用 npx create-next-app@latest --typescript 创建 TypeScript 应用程序时,您可以开始导入 *.css 文件(例如)并获得正确的类型。

我感到困惑的地方是我最初认为类型来自 next-env.d.ts 但即使我删除了文件,*.css 导入仍在 Visual Studio 代码中工作.但原因是 pages 目录中的一个文件正在导入 Next.js' index.d.ts 文件。

基本上,在 Visual Studio 代码中,一旦您在项目中的某处导入了一个类型,如果它是全局的,那么它就可以随处访问。

解决方法

那么当前的 TypeScript 功能可以做什么呢?要支持新的文件类型,您将需要一个文件加载器,例如 Webpack。合乎逻辑的做法是在文件加载器本身中添加对文件类型声明的引用。这样,只要您将文件加载器配置为能够导入文件,您就会继承类型:

  1. 在我们的包的源目录中创建一个 txt.d.ts(例如 src)——您可以为该文件使用任何名称,这并不重要
  2. 如果您使用的是 eslint,请添加一个条目以忽略类型文件(例如 'src/*.d.ts' 在您的 ignorePatterns 选项中
  3. 由于您要在源中添加一个不受 tsc 管理的 d.ts 文件,因此您需要添加一个脚本来执行以下操作:
    1. txt.d.ts复制到你的包的编译文件的目标目录中
    2. 将此行添加到包文件加载器的顶部(例如 loader/index.d.ts: /// <reference types="../txt" />\r\n - 这会将 link 声明文件放回包中。请注意,您可以添加this reference to your package.

此变通方法仅在您导入引用回声明的文件后才有效 - 这是让 TypeScript 知道此类型存在的唯一方法(请参阅 https://github.com/microsoft/TypeScript/issues/49124)。

另一种替代方法也可以是添加手动步骤(在自述文件中)以添加全局类型声明文件。